-2

当我尝试从存储过程中的动态 T-SQL 查询中输出一个值时,我遇到了一个问题。

我尝试执行以下操作,如果发现某些内容,则简单地输出 1:

SET NOCOUNT ON
DECLARE @returnValue int
DECLARE @Statement nvarchar(400)
set @Statement = 'SELECT @result=''1'' FROM INFORMATION_SCHEMA.COLUMNS
                  WHERE TABLE_NAME = ''sourceTable''
                  AND COLUMN_NAME = @columnIN
                  AND TABLE_SCHEMA = ''dbo'''
exec sp_executesql @Statement, 
    N'@columnIN nvarchar(60),@result INT OUTPUT', 
    @columnIN = @column, @result=@returnValue OUTPUT    
select @returnValue      

这目前产生NULL. 有谁知道我错过了什么?

附加信息:我尝试查找的列例如 column1 。如果我运行 SQL 查询,...AND CLOUMN_NAME = 'column1' ...我会得到 1。如果我在 SP 中打印@column变量,我会得到“column1”。 @column在 SP 中使用 nvarchar(60) 声明为输入变量:PROCEDURE [dbo].[usp_checkColumn] (@column nvarchar(60), @result INT OUTPUT)

根据要求,完整的 SP 在这里:

  Create PROCEDURE [dbo].[usp_checkColumn] (@column nvarchar(60), @result INT OUTPUT)
AS
BEGIN

    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON
    DECLARE @returnValue int
    DECLARE @Statement nvarchar(400)
    set @Statement = 'SELECT @result=''1'' FROM INFORMATION_SCHEMA.COLUMNS
                       WHERE TABLE_NAME = ''t_table''
                       AND COLUMN_NAME = @columnIN
                        AND TABLE_SCHEMA = ''dbo'''

    exec sp_executesql @Statement, N'@columnIN nvarchar(60),@result INT OUTPUT', @columnIN = @column, @result=@returnValue OUTPUT    
    select @returnValue      
    return @returnValue

END

这就是我如何称呼 SP:

DECLARE fcursor CURSOR
FOR
  select FieldName 
  from t_fieldDefinition 
OPEN fcursor

Fetch next from fcursor into @field;  
WHILE @@FETCH_STATUS = 0
BEGIN
  SET @tmpField = '''' + @field + ''''
  SET @field ='[' + @field  + ']' 
  set @available = 0 
  exec usp_checkColumn @tmpField,@available OUTPUT

如果我在 usp_checkColumn 中打印 [@column] 变量,我确实会在“”中得到正确的列。如果我复制并粘贴此变量的打印并将其插入到查询中,我会返回 1,如果我运行 SP,我会返回 NULL(转换为 0,因为 NULL 对 INT 变量无效)。

这是 t_fieldDefinition 表的内容:

FieldName   ID
Source      5
column1     6
column2     7
Client      8
asd BSX     9
bsd         10
esd         11
esx         12

这是 t_table 表的定义:

ID          bigint          Unchecked
Source      varchar(250)    Checked
column1     varchar(250)    Checked
column2     nvarchar(100)   Checked
Client      varchar(10)     Checked
asd         varchar(250)    Checked
[asd BSX]   varchar(250)    Checked

所以这意味着它应该为表定义内的所有内容返回 1,为所有其他内容返回 0。带有空格的字段是否可能是问题所在?尽管当您手动执行时它们也能正常工作。并不是说我真的可以选择更改它,但至少我现在会是问题的原因。

4

1 回答 1

0

我将冒险回答这个问题。

我不建议使用游标来遍历每一列,只是为了测试该列是否存在于另一个表中。如果您坚持使用游标,则可以使用子查询将循环通过的结果限制为仅在另一个表中不存在的列,从而无需存储过程单独检查每个列(其中顺便说一句,我认为作为用户功能更有意义):

DECLARE fcursor CURSOR
FOR
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
where table_name = 't_table' and not column_name in 
(   
    SELECT COLUMN_Name FROM INFORMATION_SCHEMA.COLUMNS
    where table_name = 't_fieldDefinition'
) 

如果您的目标确实是更改表以添加任何缺少的列,那么可以通过消除游标并使用 FOR XML 输出结果来改进这一点:

declare @sql varchar(max)
set @sql = 
(
    SELECT cast('ALTER TABLE t_fieldDefinition ADD [' + COLUMN_NAME + '] INT;' as varchar(max)) FROM INFORMATION_SCHEMA.COLUMNS
    where table_name = 't_table' and not column_name in 
    (   
        SELECT COLUMN_Name FROM INFORMATION_SCHEMA.COLUMNS
        where table_name = 't_fieldDefinition'
    ) FOR XML PATH ('')
)
print @sql
exec (@sql)
于 2013-05-24T19:50:10.473 回答