PHP Script Transformando Linhas de um Arquivo em Cláusula SQL IN

php process-file-lines-into-sql-in-clause.php --filename=original-file-with-ids-extracted-from-spreadsheet-column --quotes=none --split=1000

Acima a sintaxe de como invocar o script, abaixo o script ele mesmo.

<?php
const HINT_FILENAME = "php process-file-lines-into-sql-in-clause.php --filename=my-text-file-name.txt";
const HINT_QUOTES = HINT_FILENAME . " --quotes=double|single|none";
const HINT_SPLIT = HINT_QUOTES . " --split=1000|none";

$options = getopt(null, ["filename:","quotes:","split:"]);

(!array_key_exists('filename',$options))
    ? die("\n*** Missing argument --filename *** ... sample of usage:\n\n" . HINT_FILENAME . "\n\n")
    : null;

(!array_key_exists('quotes',$options))
    ? die("\n*** Missing argument --quotes *** ... sample of usage:\n\n" . HINT_QUOTES . "\n\n")
    : null;

(!array_key_exists('split',$options))
    ? die("\n*** Missing argument --split *** ... sample of usage:\n\n" . HINT_SPLIT . "\n\n")
    : null;

$filename = $options['filename'];
$quotes = $options['quotes'];
$split = $options['split'];

switch ($quotes) {
  case "double":
    $quotes = '"';
    break;
  case "single":
    $quotes = "'";
    break;
  case "none":
  default:
    $quotes = "";
}

$filename_original_renamed = date('Ymd') . '-source-' . $filename;
$file_content_rows = file($filename, FILE_IGNORE_NEW_LINES);

$split = is_numeric($split) ? (int)$split : count($file_content_rows);
$chunks = array_chunk($file_content_rows, $split);

echo "\n\nYour file lines are being processed and converted to a string of SQL IN clause";
echo "\nTotal Rows=" . count($file_content_rows);
echo "\n";

$glue = (empty($quotes)) ? ',' : $quotes . ',' . $quotes;

foreach ($chunks as $chunk => $chunk_rows) {
    $chunk_label = count($chunks) > 1 ? '-chunk-' . str_pad($chunk+1, 3, '0', STR_PAD_LEFT) : '-lines-' . $split;
    $filename_processed_renamed = date('Ymd') . '-processed-' . $filename . $chunk_label;
    $stringifyEmails = $quotes . implode($glue, $chunk_rows) . $quotes;
    file_put_contents($filename_processed_renamed, $stringifyEmails);

    echo "\nFile content processed and save onto a renamed file... " . $filename_processed_renamed;
}

rename($filename, $filename_original_renamed);

echo "\n\nYour original source file has been renamed to... " . $filename_original_renamed;
echo "\n\n";

Pessoal sem delongas… Sabem quando você tem aquela planilha lotada de IDs que passaram pra você fazer um SQL?

Pois é, até dá pra formatar na mão os IDs como sendo uma lista separadas por vírgulas e eventualmente recobertos por aspas ou algo assim.

Mas e se a planilha tiver 100.000 linhas ou mais? E se o SQL que você precisa rodar for na verdade um DML? E se você precisar executar as ações em volumes menores pra não sobrecarregar o servidor? Hã?

Pra isso eu desenvolvi este super script Tabajara que resolve o seu problema, veja que legal o pocesso.

Passo 1) copie e cole a coluna de IDs num arquivo texto tipo Brackets, Notepad++, VI ou outro editor qualquer de sua preferência, e salve no disco.

1140178
1141171
1166736
1177320
1193872
1212530

Passo 2) execute o script conforme demonstrado no primeiro bloco deste artigo, logo vou explicar as opções.

php process-file-lines-into-sql-in-clause.php --filename=original-file-with-ids-extracted-from-spreadsheet-column --quotes=none --split=none

Passo 3) colete no próprio diretório os arquivos processados com conteúdo no formato SQL IN.

1140178,1141171,1166736,1177320,1193872,1212530

Passo 4) se precisar, colete seu arquivo original que foi renomeado com o termo “source“.

Explicando as opções do Script:

  • filename nome do arquivo fonte contendo os respectivos elementos, sempre 1 por linha
  • quotes deve ser informado um valor entre double|single|none para que elemento seja recoberto por aspas no caso de ser uma string
  • split deve ser informado um valor inteiro com a quantidade de registros máximos a serem gerados no arquivo processado. No caso serão gerados tantos arquivos quanto necessário que serão separados como chunks, contendo sempre a quantidade máxima exceto o último que poderá conter um volume menor.

Pronto, você está pronto para copiar a string com os IDs para serem inseridos numa cláusula SQL IN. Fique sabendo também que exatamente a mesma formatação para lista do SQL IN serve para criar um array no PHP, basta recobrir com squared brackets [] ao invés de brackets ().

Pra finalizar quero citar que o mesmo resultado pode ser alcançado com editores de texto ou IDEs com o auxílio do mouse e bastante paciência.

Eu também sei que dá pra fazer isso com o editor de texto VI usando macro substituições, mas eu nunca fiz e não sei fazer, mas eu sei quem sabe!

Mas isso é assunto para outro artigo!