使用 BAT 文件的 BIG 查询命令

BIG Query command using BAT file

echo Give yearmonth "yyyyMM"
setlocal enabledelayedexpansion
SET /p yearmonth= 
SET ClientName[0]=abc
SET ClientName[1]=def

SET i = 0

:myLoop
if defined ClientName[%i%] (
    call bq query --use_legacy_sql=false "CREATE EXTERNAL TABLE `test.!ClientName[%%i]!.%yearmonth%` OPTIONS (format = 'CSV',skip_leading_rows = 1 uris = ['gs://test/!ClientName[%%i]!/AWS/%yearmonth%/Metrics/data/*.csv'])"
    set /a "i+=1"
    GOTO :myLoop

)

你好,我正在尝试创建一个批处理,这样我就可以同时 运行 多个 BIG QUERY。 上面我试着写了一个批处理脚本,把命令放在一个循环中。

我正在尝试通过使用年月作为用户输入来创建 table,然后创建数组以创建具有不同客户端名称的 table。

  1. 但是如果我在呼叫查询中使用 i =0 ClientName[i] = abc 我无法打印 !ClientName[%%i]! 打印但它不工作。

  2. 在 GCP 控制台中,当我执行 bat 文件时,循环内的调用查询不是 运行ning。

你能帮我解决这个问题吗

  1. set 变量作为独立的字母字符(如 i)是不好的做法。一个原因正是您所经历的,您将 for 元变量 %%iset 变量 %i%.

    混淆了
  2. 你在循环中展开,但没有enabledelayedexpansion所以有两种方法,我们稍后会讲到。

  3. setting 变量在 = 之前或之后不应有空格,但 set /a

    除外

所以,方法 1,没有 delayedexpansion(注意变量如何在循环中与 call 命令一起使用双 %%)。

@echo off
echo Give yearmonth "yyyyMM"
SET /p yearmonth= 
SET ClientName[0]=abc
SET ClientName[1]=def

SET num=0

:myLoop
if defined ClientName[%num%] (
    call bq query --use_legacy_sql=false "CREATE EXTERNAL TABLE `test.%%ClientName[%num%]%%.%yearmonth%` OPTIONS (format = 'CSV',skip_leading_rows = 1 uris = ['gs://test/%%ClientName[%num%]%%/AWS/%yearmonth%/Metrics/data/*.csv'])"
    set /a num+=1
    GOTO :myLoop

)

方法 2:(使用 delayedexpansion 的更好方法)

@echo off
setlocal enabledelayedexpansion
echo Give yearmonth "yyyyMM"
SET /p yearmonth= 
SET ClientName[0]=abc
SET ClientName[1]=def

SET num=0

:myLoop
if defined ClientName[%num%] (
    call bq query --use_legacy_sql=false "CREATE EXTERNAL TABLE `test.!ClientName[%num%]!.%yearmonth%` OPTIONS (format = 'CSV',skip_leading_rows = 1 uris = ['gs://test/!ClientName[%num%]!/AWS/%yearmonth%/Metrics/data/*.csv'])"
    set /a num+=1
    GOTO :myLoop

)

我会选择更直观的循环机制:

For /F "Tokens=1,* Delims==" %%G In ('"(Set ClientName[) 2>NUL"') Do Call "%ProgramFiles%\Google\Cloud SDK\google-cloud-sdk\bin\bq.cmd" query --use_legacy_sql=false "CREATE EXTERNAL TABLE `test.%%G.%yearmonth%` OPTIONS (format = 'CSV',skip_leading_rows = 1 uris = ['gs://test/%%G/AWS/%yearmonth%/Metrics/data/*.csv'])"

它不需要延迟扩展或变量递增,如果没有定义名为 ClientName[n] 的变量,则什么也不做。

因此这意味着您可以列出您的变量,但在某些时候评论一个或多个:

Set "ClientName[0]=abc"
Set "ClientName[1]=def"
Rem Set "ClientName[2]=ghi"
Set "ClientName[3]=jkl"

当循环运行时,与递增机制不同,不会对带括号的If Defined %ClientName[2]% …代码块进行不必要的解析。

但是,您的问题中有几件事可能会引发潜在问题。最大的问题是您看似期待用户输入,但同时相信输入已经提供,并且格式符合您的期望。在编写需要交互的脚本时,您必须始终假设最终用户不能或不会始终遵循说明。

因此,这里有一个设计更强大的脚本来执行您的预期查询:

@Echo Off
SetLocal EnableExtensions DisableDelayedExpansion

Rem Define a variable named bq pointing to your bigquery batch file.
Set "bq=%ProgramFiles%\Google\Cloud SDK\google-cloud-sdk\bin\bq.cmd"

Rem If the bigquery batch file does not exist, terminate the script.
If Not Exist "%bq%" Exit /B

Rem Ensure that there are not existing ClientName[n] variables defined.
For /F "Delims=" %%G In ('"(Set ClientName[) 2>NUL"') Do Set "%%G="

Rem Define your ClientName[n] variable list.
Set "ClientName[0]=abc"
Set "ClientName[1]=def"

:GetYearMonth
Rem Ensure that no existing variable named YearMonth is defined.
Set "YearMonth="

Rem Request user input of date saved to the variable named YearMonth.
Set /P "YearMonth=Please provide the date in the format yyyyMM>" 

Rem If no input was received, ask again.
If Not Defined YearMonth GoTo GetYearMonth

Rem Remove any doublequotes from the YearMonth variable value.
Set "YearMonth=%YearMonth:"=%"

Rem If YearMonth variable value is not within allowed range, ask again.
Rem This example uses 197001 - 202212
(Set YearMonth) 2>NUL | %SystemRoot%\System32\findstr.exe /R^
 /C:"^YearMonth=19[789][0123456789]0[123456789]$"^
 /C:"^YearMonth=19[789][0123456789]1[012]$"^
 /C:"^YearMonth=20[01][0123456789]0[123456789]$"^
 /C:"^YearMonth=20[01][0123456789]1[012]$"^
 /C:"^YearMonth=202[012]0[123456789]$"^
 /C:"^YearMonth=202[012]1[012]$"^
 1>NUL || GoTo GetYearMonth

Rem As input information is valid loop your command.
For /F "Tokens=1,* Delims==" %%G In ('"(Set ClientName[) 2>NUL"'
) Do Call "%bq%" query --use_legacy_sql=false "CREATE EXTERNAL TABLE `test.%%G.%YearMonth%` OPTIONS (format = 'CSV',skip_leading_rows = 1 uris = ['gs://test/%%G/AWS/%YearMonth%/Metrics/data/*.csv'])"

EndLocal