2017-12-27 44 views
1

Ich versuche, eine SQL von der Linux-Befehlszeile für ein BQ-Tabellenziel auszuführen. Dieses SQL-Skript wird für mehrere Datumsangaben, Clients und BQ-Tabellenziele verwendet. Dies würde die Verwendung von Parametern in meinen BQ-API-Befehlszeilenaufrufen erfordern (das Flag -Parameter). Nun bin ich diesem Link gefolgt, um mehr über parametrisierte Abfragen zu erfahren: https://cloud.google.com/bigquery/docs/parameterized-queries, aber es ist begrenzt bei der Erklärung eines Tabellennamens.Google BQ: Ausführen von parametrisierten Abfragen, bei denen die Parametervariable das BQ-Tabellenziel ist

My SQL-Skript, genannt Advertiser_Date_Check.sql, ist die folgende:

#standardSQL 
SELECT * 
FROM (SELECT * 
     FROM @variable_table 
     WHERE CAST(_PARTITIONTIME AS DATE) = @variable_date) as final 
WHERE final.Advertiser IN UNNEST(@variable_clients) 

Wo die Parametervariablen die folgenden darstellen:

  • variable_table: Das BQ Tabelle Ziel, das ich
  • anrufen möchten
  • variable_date: Das Datum, das ich aus der BQ-Tabelle ziehen möchte
  • variable_clients: Eine Array-Liste von bestimmten Clients, die ich wa nt aus den Daten zu ziehen (die ab dem Zeitpunkt I verwiesen)

Nun, meine Commandline (Linux) für die BQ-Daten sind die folgenden

TABLE_NAME=table_name_example 
BQ_TABLE=$(echo '`project_id.dataset_id.'$TABLE_NAME'`') 
TODAY=$(date +%F) 

/bin/bq query --use_legacy_sql=false \ 
     --parameter='variable_table::'$BQ_TABLE'' \ 
     --parameter=variable_date::"$TODAY" \ 
     --parameter='variable_clients:ARRAY<STRING>:["Client_1","Client_2","Client_3"]' \ 
     "`cat /path/to/script/Advertiser_Date_Check.sql`" 

Die Parameter @variable_date und @variable_clients haben in der Vergangenheit gut funktioniert, als es nur sie waren. Da ich jedoch diesen genauen SQL-Befehl für verschiedene Tabellen in einer Schleife ausführen möchte, habe ich einen Parameter namens variable_table erstellt. Parametrisierte Abfragen haben in Standard-SQL-Format sein, so dass der Tabellennamenskonvention in einem solchen Format sein muss:

`project_id.dataset_id.table_name` 

Jedes Mal, wenn ich versuche, dies auf der Kommandozeile zu laufen, ich in der Regel die folgende Fehlermeldung erhalten:

Error in query string: Error processing job ... : Syntax error: Unexpected "@" at [4:12] 

Die bezieht sich auf den Parameter @variable_table, so ist es eine harte Zeit Verarbeitung, dass dies einen Tabellennamen verweist. In früheren Versuchen, es hat sogar der Fehler gewesen:

project_id.dataset_id.table_name: command not found 

Aber das war meist aufgrund der schlechten Referenzzielnamentabelle. Der erste Fehler ist das häufigste Vorkommen.

Insgesamt meine Fragen in dieser Angelegenheit sind:

  1. Wie ich eine BQ Tabelle als Parameter in der Kommandozeile für parametrisierte Abfragen verweisen, enthalten die in FROM-Klausel (wie, was ich versuche, mit @variable_table zu tun) Ist es überhaupt möglich?
  2. Kennen Sie andere Methoden, um eine Abfrage auf mehreren BQ-Tabellen von der Befehlszeile aus neben der Art, wie ich es gerade mache?

Hoffe, das alles macht Sinn und danke für Ihre Hilfe!

+0

Aus der verknüpften Dokumentation können "Parameter nicht als Ersatz für Bezeichner, Spaltennamen, Tabellennamen oder andere Teile der Abfrage verwendet werden." –

+0

Oh mein Gott. Ich muss diesen Teil einfach verpasst haben. Es war ein ziemlich langer Tag. Danke für die Antwort. –

+2

Ich denke, was für Sie funktioniert, ist die Injektion des Tabellennamens als reguläre Shell-Variable (anstelle eines Abfrageparameters). Sie sollten jedoch sicherstellen, dass Sie den Inhalt der Nachricht als vertrauenswürdig einstufen oder dass Sie die Zeichenfolge selbst erstellen, um eine SQL-Injektion zu vermeiden. –

Antwort

2

Aus der Dokumentation, die Sie verknüpft:

Parameters cannot be used as substitutes for identifiers, column names, table names, or other parts of the query.

Ich denke, was in diesem Fall für Sie arbeiten, obwohl, ist die Injektion des Tabellennamens als reguläre Shell-Variable (anstelle eines Abfrageparameter durchführen). Sie sollten sicherstellen, dass Sie dem Inhalt vertrauen oder dass Sie die Zeichenfolge selbst erstellen, um eine SQL-Injektion zu vermeiden. Ein Ansatz besteht darin, fest codierte Konstanten für die Tabellennamen zu haben und dann auszuwählen, welche basierend auf der Benutzereingabe in den Abfragetext einzufügen sind.

Verwandte Themen