4

現在、1つのユーザー名を読み取り、SQLで使用する次のバッチコードがあります

@echo on
cls
set userID=
for /F %%i in (UserID.txt) do set userID=%userID% %%i
sqlcmd -S server -d database -U username -P password -v userID=%userID% 
                -i "sqlQuery.sql" -s "," > "\output.csv" -I -W -k

呼び出される SQL クエリは次のとおりです。

SELECT userId, COUNT (*) AS number 
FROM table 
WHERE userId = '$(userID)' 
GROUP BY userId 
ORDER BY userId desc

私が探しているのは、テキスト ファイルにユーザー名のリストがある場合、WHERE ステートメントが動的に変更されることです。

WHERE userId = '$(userID1)' OR userId = '$(userID2)' etc....
4

2 に答える 2

5

私は SQL スクリプトをあまり扱っていないので、戻り値が問題を引き起こすかどうかはわかりませんが、これにより必要なものが生成されます。

この入力を userID.txt というファイルで使用しました。

steve,joe,fred,jason,bill,luke

このコードを実行しました:

@echo off
setlocal enabledelayedexpansion
set count=0
for /F "tokens=* delims=," %%G in (userID.txt) do call :loop %%G
:loop
if "%1"=="" goto :endloop
set /a count+=1
set userid%count%=%1
SHIFT
goto :loop
:endloop
set totalusers=%count%
set /a totalusers-=1

echo SELECT userId, COUNT (*) AS number FROM table WHERE ( > sqlQuery.sql
set count=0
:where_gen_loop
set /a count+=1
if !count! gtr !totalusers! goto endwhere_gen_loop
echo userId = '$(!userid%count%!)' OR>> sqlQuery.sql
goto where_gen_loop
:endwhere_gen_loop
echo userId = '$(!userid%count%!)'>> sqlQuery.sql
echo ) >> sqlQuery.sql
echo GROUP BY userId ORDER BY userID desc >> sqlQuery.sql

sqlQuery.sql でこの出力を生成しました。

SELECT userId, COUNT (*) AS number FROM table WHERE ( 
userId = '$(steve)' OR
userId = '$(joe)' OR
userId = '$(fred)' OR
userId = '$(jason)' OR
userId = '$(bill)' OR
userId = '$(luke)'
) 
GROUP BY userId ORDER BY userID desc 

その後、バッチの最後にアクセスされます。

sqlcmd -S server -d database -U username -P password -i "sqlQuery.sql" -s "," > "\output.csv" -I -W -k

endlocal
于 2012-04-05T18:28:34.170 に答える
4

SQL クエリを変更して IN 句を使用し、変数を適切にフォーマットするだけです。また、%userID% は FOR ステートメントが解析されるときに 1 回だけ展開されるため、FOR ループ内で遅延展開を使用する必要がありますが、!userID! 各ループ反復の実行時に展開されます。

sqlQuery.sql:

SELECT userId, 
       COUNT(*) AS number
  FROM table
 WHERE userId in( $(userID) )
 GROUP BY userId
 ORDER BY userId desc

バッチ スクリプト:

@echo on
setlocal enableDelayedExpansion
set userID=
for /f %%i in (UserID.txt) do set "userID=!userID!,'%%i'"
sqlcmd -S server -d database -U username -P password -v userID="%userID:~1%" -i "sqlQuery.sql" -s "," > "\output.csv" -I -W -k

sql 変数の定義では、バッチ部分文字列操作を使用して先頭のコンマを削除していることに注意してください。

userID 変数は最終的に次のようになります'userID1','userID2','userID3'

入力ファイル内の ID が多すぎて 8k 環境変数の制限内に収まらない場合は、SQL スクリプトを動的に構築する必要があります。その時点で、sql 変数を削除して、単純に文字列リテラルを使用することもできます。

@echo on
setlocal enableDelayedExpansion
set "delim="
>"sqlQuery.sql" echo SELECT userId, COUNT(*) AS number FROM table WHERE userId in(
for /f %%i in (UserID.txt) do (
  >>"sqlQuery.sql" echo !delim!'%%i'
  set "delim=,"
)
>>"sqlQuery.sql" echo ) GROUP BY userId ORDER BY userId desc
sqlcmd -S server -d database -U username -P password -i "sqlQuery.sql" -s "," > "\output.csv" -I -W -k
于 2012-04-05T20:12:21.933 に答える