使用 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。
但是如果我在呼叫查询中使用 i =0 ClientName[i] = abc 我无法打印 !ClientName[%%i]! 打印但它不工作。
在 GCP 控制台中,当我执行 bat 文件时,循环内的调用查询不是 运行ning。
你能帮我解决这个问题吗
将 set
变量作为独立的字母字符(如 i
)是不好的做法。一个原因正是您所经历的,您将 for
元变量 %%i
与 set
变量 %i%
.
混淆了
你在循环中展开,但没有enabledelayedexpansion
所以有两种方法,我们稍后会讲到。
set
ting 变量在 =
之前或之后不应有空格,但 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
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。
但是如果我在呼叫查询中使用 i =0 ClientName[i] = abc 我无法打印 !ClientName[%%i]! 打印但它不工作。
在 GCP 控制台中,当我执行 bat 文件时,循环内的调用查询不是 运行ning。
你能帮我解决这个问题吗
将
混淆了set
变量作为独立的字母字符(如i
)是不好的做法。一个原因正是您所经历的,您将for
元变量%%i
与set
变量%i%
.你在循环中展开,但没有
enabledelayedexpansion
所以有两种方法,我们稍后会讲到。
除外set
ting 变量在=
之前或之后不应有空格,但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