如何在SQLCMD中抑制连字符

时间:2010-03-02 09:57:03

标签: sql-server sqlcmd

如何从此sqlcmd命令的结果集中抑制连字符(------------):

C:\temp>sqlcmd -d AdventureWorks -s ";" 
 -Q "SET NOCOUNT ON SELECT top 5 FirstName, LastName FROM Person.Contact;"
FirstName                                         ;LastName
--------------------------------------------------;----------------------------
Gustavo                                           ;Achong
Catherine                                         ;Abel
Kim                                               ;Abercrombie
Humberto                                          ;Acevedo
Pilar                                             ;Ackerman

C:\temp>

18 个答案:

答案 0 :(得分:14)

我唯一能想到的是使用-h -1开关删除标题并将列名添加为SQL查询的第一行:

SELECT 'FirstName' as FirstName, 'LastName' as LastName
UNION
SELECT top 5 FirstName, LastName FROM Person.Contact

请注意,如果还有其他数据类型(var)char,则需要使用以下字段转换字段:CAST(MyColumnName AS varchar(32)) as MyColumnName

答案 1 :(得分:11)

我没有在一个地方看到所有这些信息,并认为下一个寻找它的人可能会欣赏它......

使用-h -1选项从输出中删除短划线(--------),并SET NOCOUNT ON删除受影响的"行#34;。如果您要为其他系统创建报告或CSV文件,这非常有用。

示例:

SQLCMD -S 127.0.0.1\SQL_SERVER_Instance -d db_name -U db_login -P password -i your_script.sql -o your_output.csv -h -1

在您的SQL脚本中:

SET NOCOUNT ON -- removes (rows affected from the output)
select 'your_column_1, your_column_2'
select * from your_table

您不需要在select语句之间使用联合。

答案 2 :(得分:9)

仅使用sqlcmd和Windows命令行,没有存储过程:

REM Get the column headers ("set nocount on" is necessary to suppress the rows affected message)
sqlcmd -S MyServer -Q "set nocount on;select top 0 * from MyDatabase.MySchema.MyTable" -o "MyTableColumns.csv" -s "," -W

REM Remove hyphen line
findstr /R /C:"^[^-]*$" MyTableColumns.csv > MyTableHeader.csv

REM Get data without headers
sqlcmd -S MyServer -Q "set nocount on;select * from MyDatabase.MySchema.MyTable" -o "MyTableData.csv" -h -1 -s "," -W
REM You can also use bcp for this step
REM bcp "select * from MyDatabase.MySchema.MyTable" queryout  "MyTableData.csv"  -c -t"," -r"\n" -S MyServer -T

REM Append header and data
type MyTableHeader.csv MyTableData.csv > MyTableDataWithHeader.csv

要处理内部分隔符的数据(例如“Atlanta,GA”),您需要单独指定字段(而不是使用“select *”)并在SQL Server中使用QUOTENAME函数。

答案 3 :(得分:4)

那就是它!

  

如何从此sqlcmd命令的结果集中抑制连字符(------------):

您可以在 1命令中完成所有操作,无需任何脚本或文件操作!

public class Person {

    String name;
    String surname;
    int age;

    List<String> friends;

    public Person(String name, String surname, int age, List<String> friends) {
      this.name = name;
      this.surname = surname;
      this.age = age;
      this.friends = friends;
    }    
}

List<String> friends = new Arraylist<String>();
friends.add("Chicken");
friends.add("Weedwacker");
friends.add("CornCob");
Person person = new Person("Name", "Surname", 42, friends);

添加sqlcmd -d AdventureWorks -s ";" -Q "SET NOCOUNT ON; SELECT top 5 FirstName, LastName FROM Person.Contact" |findstr /v /c:"---" 以删除set nocount on;行。 添加 (X rows affected) 以删除下划线。 这样你就得到一个干净的答案,只有:

|findstr /v /c:"---"

答案 4 :(得分:3)

或者也许可以通过sed将输出后处理为:

sqlcmd ... | sed -e '2d'

删除第二行?

您可以从http://gnuwin32.sourceforge.net/packages/sed.htm

获取Win32 sed

答案 5 :(得分:2)

为了摆脱连字符,我在我的存储过程中添加了一些代码,这些代码只会输出列标题。使用SQLCMD提取数据分为两部分。

首先,我使用一组特殊参数调用我的存储过程。在我的情况下,当我用所有NULL调用SP时,它意味着我希望有列标题。

然后我再次调用SQLCMD并将输出附加到我之前创建的文件中,然后瞧!

创建一个空白CSV文件以保存列标题

sqlcmd -S server -d database -U username -P password -o "somefile.csv" -h-1 
  -Q "exec myStoredProcedure NULL, NULL" -W -w 2000 -s"," > sometextfile.csv

现在追加存储过程的输出结果

sqlcmd -S server -d database -U username -P password -o "somefile.csv" -h-1 
  -Q "exec myStoredProcedure 2011, 10" -W -w 2000 -s"," >> sometextfile.csv

注意第一个命令使用&gt; ,第二个命令使用&gt;&gt; 。使用时 - > “创建或覆盖”和两个 - &gt; “追加或创造”。

  • -h-1删除SQLCMD生成的标头
  • -W删除尾随空格
  • -w设置最大行宽
  • -s定义列分隔符

答案 6 :(得分:1)

您可以执行以下操作:

exec 'sqlcmd -S YourServer -E -Q "set nocount on; select * from YourTable" -s "," -W | findstr /R /C:"^[^-]*$" > yourfile.csv'

这将创建一个带头的csv文件,其中没有破折号,并且修剪了空白,一口气。基于上述MichaelM的答案。

答案 7 :(得分:1)

我不得不做大量的研究,因为这里的答案都不符合我的要求。因此,我希望能够帮助其他人。

对我来说,最简单的方法是使用sed。虽然这里已经提到了这一点,但是运行sqlcmd和sed的语法不正确。如果你正在使用Windows,就像我一样,请前往http://gnuwin32.sourceforge.net/packages/sed.htm下载sed

我的最终命令看起来像:

SQLCMD -m 1 -S "userpc\SQLEXPRESS" -E -i "C:\someDirectory\sqlfile.sql" -W -s "," -o "C:\someDirectory\output.csv" && sed -i 2d "C:\someDirectory\output.csv"

其中

- -m 1消除了“将数据库上下文更改为...”行 - 如果第一个命令成功运行,则&&运行第二个命令 - sed -i 2d删除包含连字符的第二行,并将sed的输出覆盖为原始输出

请注意,sed输出文件名和sqlcmd的输出必须匹配,否则sqlcmd的输出将无法正确覆盖。如上所述,2d语句中的sed周围不应有引号,并且会出现在文档中,否则您将收到错误。

希望这有帮助!

答案 8 :(得分:0)

这就是我最终得到的结果,并且对我来说效果很好:

sqlcmd -S 12.34.56.789 -i "C:\Qry.sql" -s"," -W -w1000 | findstr /V /R /C:"^[-,]*$" > Reprt.csv

我相信在这一点上,仅需对findstr和regex进行解释:

findstr /V /R /C:"^[-,]*$"

正则表达式表示“在开始^处,-{或[-,]的次数是*的任意倍,直到到达行$的末尾为止。

/V的意思是,告诉我所有不匹配的内容。

其后的>将显示重定向到文件。

我也确实将此添加到了我的SQL文件中:

SET NOCOUNT ON;

答案 9 :(得分:0)

我通常按以下方式处理生成的.csv文件:

sed -i '2d' "$file"  # remove 2nd line of dashes
sed -i '$d' "$file"  # remove last line (row count string)
sed -i '$d' "$file"  # remove one more empty line at the end of the file

位置:

  • -i就地编辑文件...
  • 2d删除第2行,在这种情况下为短划线...
  • $d删除文件末尾的单行...
  • "$file"是bash变量,用于保存.csv文件的路径字符串。

答案 10 :(得分:0)

从结果中删除破折号:

EXEC msdb.dbo.sp_send_dbmail
@profile_name = 'testMail',
@recipients = 'krishan@gmail.com',
@query = '  
SET NOCOUNT ON
SELECT W.* FROM (
(SELECT CAST("id" AS VARCHAR(5) ) as id , CAST("name" AS VARCHAR(50) )as name ) 
UNION ALL 

SELECT CAST( id AS VARCHAR(5) ) AS id, CAST (name AS VARCHAR(50) ) AS name from mydb.dbo.bank
 )W
' ,
@subject = 'Test email',
@attach_query_result_as_file = 1,
@query_attachment_filename='filename.xls',
@query_result_separator='   ',   
@query_result_header = 0

    -----remember @query..separator should be--Tab space----

答案 11 :(得分:0)

Public Sub HyphenDelete(strFilename1 As String, Hyphens As Integer)


Const FOR_READING = 1
Const FOR_WRITING = 2

strFileName = strFilename1

strCheckForString = Left("-------", Hyphens)
Set objFS = CreateObject("Scripting.FileSystemObject")
Set objTS = objFS.OpenTextFile(strFileName, FOR_READING)
strContents = objTS.ReadAll
objTS.Close

arrLines = Split(strContents, vbNewLine)
Set objTS = objFS.OpenTextFile(strFileName, FOR_WRITING)

For Each strLine In arrLines
   If Not (Left(UCase(LTrim(strLine)), Len(strCheckForString)) = strCheckForString) Then
      objTS.WriteLine strLine
   End If
Next

End Sub

答案 12 :(得分:0)

MichaelM有一个不错的解决方案,但正如弹弓指出的那样...... findstr可能过于激进并删除包含连字符的数据行。另一种方法是调用sqlcommand获取数据集,然后使用set / p从输出文件中获取第一行并将其分配给变量。然后删除orignal输出文件。接下来,将标头回显到新文件。最后,将另一个无头sqlcmd传递给该文件。

sqlcmd -S server -d database -E -Q "exec myStoredProcedure" -W -o my_headers.csv -m-1
set /p headers=< my_headers.csv
del my_headers.csv
echo %headers% > my_data.csv
sqlcmd -S server -d database -E -Q "exec myStoredProcedure" -W -m-1 -h-1 >> my_data.csv

同样,Top 0是创建&#34;头文件的最佳选择&#34;但仅当您使用select语句时。如果您正在调用存储过程,请查看使用FMTONLY ON仅从SP获取标头。

sqlcmd -S server -d database -E -Q "Set NOCOUNT ON; Set FMTONLY ON; exec myStoredProcedure" -W -o my_headers.csv -m-1

需要注意的是,使用#temp表不能使用FMTONLY ON来对付SP。这是因为FMTONLY ON不会执行SP。它只抓取元数据。但是,如果列名来自于预先执行时不存在的表,那么您就无法获得这些列名。

  • 特洛伊

答案 13 :(得分:0)

如果您可以先输出(使用-o选项),则使用的另一个后处理选项可以通过读取文件的内容来工作 - 而跳过第二行 - 并将其写回自身。

(Get-Content "file.txt" | Where {$_.ReadCount -ne 2}) | Set-Content "file.txt"

答案 14 :(得分:-1)

如果输出到文件,请在成功执行后尝试以下操作:

    findstr /v /c:"---" sqloutput.dat > finaloutput.dat

我用&#34; ---&#34;因为我的所有列都超过3个字符而且我的数据中没有该字符串,但您也可以使用&#34; - ; - &#34;根据您的数据代替&#34;;&#34;进一步降低风险或任何分隔符。

答案 15 :(得分:-1)

如果要将数据假脱机,则可以设置以下开关:

SET UNDERLINE OFF;

答案 16 :(得分:-1)

以下一行:

findstr /R /C:"^[^-]*$" MyTableColumns.csv > MyTableHeader.csv

非常危险,因为它会删除包含“ - ”的所有行。 你最好看一下findstr /?并使用类似的东西:

findstr /B /V /C:"-----" MyTableColumns.csv > MyTableHeader.csv

答案 17 :(得分:-5)

我认为没有任何选择可以达到这个目标 - 我不得不忍受这些标题,我担心。

相关问题