【问题标题】:confusion with quotes and double quotes in a query查询中的引号和双引号混淆
【发布时间】:2012-06-19 06:38:22
【问题描述】:

我有一个很好用的查询:

CREATE Procedure BCP_Text_File
(  
    @table varchar(100),  
    @FileName varchar(100)  
)  
AS
    If exists(Select * from information_Schema.tables where table_name=@table)
    Begin
        Declare @str varchar(1000)  
        set @str='Exec Master..xp_Cmdshell ''bcp "Select * from '+db_name()+'..'+@table+'" queryout "'+@FileName+'" -c'''  
        Exec(@str)  
    end
    else
        Select 'The table '+@table+' does not exist in the database'

但我需要在其中添加:

select column_name 
from information_schema.columns
where table_name = @table
order by ordinal_position

到目前为止我有:

   alter Procedure BCP_Text_File
   (  
      @table varchar(100),  
      @FileName varchar(100)  
    )  
    AS 
       If exists(Select * from information_Schema.tables where table_name=@table)
       Begin
           Declare @str varchar(1000)  
           set @str='Exec Master..xp_Cmdshell ''bcp "

           select column_name 
           from information_schema.columns
           where table_name = '+db_name()+'..'+@table+'
           order by ordinal_position

           Select * from '+db_name()+'..'+@table+'" queryout "'+@FileName+'" -c'''  
           Exec(@str)  
       end
       else
           Select 'The table '+@table+' does not exist in the database'

但我认为我放错了单引号和/或双引号。我正在添加此选择语句,以便我的结果将字段名称作为第一行。

非常感谢您的帮助或指导。

【问题讨论】:

  • 调试 101:将 EXEC(@str) 更改为 PRINT(@str)
  • 那些'..' 真的在查询中吗?
  • @AaronBertrand 很抱歉,我无法更改它。我无法编译它
  • 你实际上想用这个来完成什么?如果您将代码out 拉出存储过程,您可以更好地调试。然后编译不会阻止您查看问题所在。如果您启用了 IntelliSense,它们甚至可能使自己变得明显。
  • 我相信这源于您其他问题的答案。既然您希望这种自动化,我可以建议您摆脱 SSMS 要求并创建一个 SQL 代理作业吗?资源不少(包括thisthisthis

标签: sql sql-server sql-server-2008 tsql ssms


【解决方案1】:

也许这就是你想要的?这假设 (a) 您的列名中没有逗号,并且 (b) 每列的输出在隐式转换为字符串时是可以的。

ALTER PROCEDURE dbo.BCP_Text_File
    @table    NVARCHAR(255),  
    @filename VARCHAR(100)  
AS
BEGIN
  SET NOCOUNT ON;

  IF OBJECT_ID(@table) IS NOT NULL
  BEGIN
    DECLARE 
        @sql NVARCHAR(MAX), 
        @cols NVARCHAR(MAX) = N'';

    SELECT @cols += ',' + name
      FROM sys.columns
      WHERE [object_id] = OBJECT_ID(@table)
      ORDER BY column_id;

    SELECT @cols = STUFF(@cols, 1, 1, '');

    SET @sql = N'EXEC master..xp_cmdshell ''bcp "SELECT ''''' 
        + REPLACE(@cols, ',', ''''',''''') + ''''' UNION ALL SELECT ' 
        + 'RTRIM(' + REPLACE(@cols, ',', '),RTRIM(') + ') FROM ' 
        + DB_NAME() + '..' + @table + '" queryout "' + @filename + '" -c''';  
    
    EXEC sp_executesql @sql;
  END
  ELSE
  BEGIN
    SELECT 'The table '+@table+' does not exist in the database';
  END
END
GO

但我必须同意你从其他人那里得到的关于这个和其他问题的建议 - 这种方法非常脆弱。你正试图用压路机打开开心果。

PS 我删除了对INFORMATION_SCHEMA 的引用,因为我认为the catalog views are more reliable and more consistent

【讨论】:

  • 非常感谢你是个宝,但是得到这个错误:未提供用户名,要么使用-U提供用户名,要么使用-T作为可信连接
  • 建议您先获得一个基本的 BCP 命令。正如错误消息所建议的那样,如果您没有使用默认实例和能够启动 bcp 并重新登录的帐户连接到服务器,则需要添加参数,例如 -U/-P 或 - T.
  • 我把 -T 放在那里了,非常感谢;但是,我查看了文件,它没有放任何逗号,只是空格作为分隔符
  • 你看过the documentation for BCP吗?有吗?来吧。就像我之前建议的那样,首先让 SIMPLE BCP 命令按照您想要的方式工作。我给你一个提示:你需要为-t 指定一些不同的东西——默认是一个标签。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-29
  • 2012-10-14
  • 1970-01-01
  • 1970-01-01
  • 2016-05-13
  • 2015-04-24
相关资源
最近更新 更多