Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 如何批量读取用户名列表并在sql语句中使用这些用户名?_Sql Server_Loops_Batch File_Sqlcmd - Fatal编程技术网

Sql server 如何批量读取用户名列表并在sql语句中使用这些用户名?

Sql server 如何批量读取用户名列表并在sql语句中使用这些用户名?,sql-server,loops,batch-file,sqlcmd,Sql Server,Loops,Batch File,Sqlcmd,目前,我有以下批处理代码来读取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 -

目前,我有以下批处理代码来读取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....

我没有太多使用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 
SELECT userId, 
       COUNT(*) AS number
  FROM table
 WHERE userId in( $(userID) )
 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

您只需修改sql查询以使用IN子句,然后正确设置变量的格式。您还必须在FOR循环中使用延迟扩展,因为在解析FOR语句时%userID%只扩展一次,而!用户ID!在每个循环迭代的执行时展开

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 
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

如果您要从批处理脚本切换到Powershell,这可能会更可行……糟糕。我以前从未使用过powershell:-/我认为您的主要限制是,对于循环,它们是单独的echo命令,这意味着输出文件中有新行。。。我不熟悉sql脚本,但如果它可以使用()中包含的多行代码,它应该可以工作。@MichaelFredrickson-这实际上是一个使用批处理解决的简单问题。看看我的答案。我相信使用Powershell以及其他任何语言都同样简单。+1当我看到人们使用Windows批处理文件获得真正的结果时,我总是印象深刻。这证明了这是可能的,但我仍然难以相信:)谢谢!我想我比其他人更喜欢批量问题,只是为了挑战因素。。。此外,我认为如果你可以使用批处理来完成一些事情,而不是vbs等。。。这意味着它可以在更多的环境中工作。总是一个加号。这个答案有很多问题:1)SQL查询错误-它将查找名为steve、joe等的变量。2)我认为输入文本文件的结构错误-原始问题意味着每行一个用户ID。3) 让代码落入子程序的错误做法。如果使用参数调用批处理,则可能会失败。4) 这比需要的复杂多了。哈哈,谢谢你的回复。就像我说的。。。我对.sql脚本了解不多,我只是根据他的要求做了他想做的事情:我要找的是,如果我在文本文件中有一个用户名列表,它将动态地更改WHERE语句:WHERE userId='$(userID1)'或userId='$(userID2)'等…+1。。。你让它看起来比我想象的在批处理脚本中简单得多。。。