2013-05-22 4 views
-2

У меня проблема. Я пытаюсь вывести значение из динамического запроса T-SQL внутри хранимой процедуры.Выходная переменная из динамического 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, @[email protected] OUTPUT  
select @returnValue  

Это в настоящее время дает NULL. Кто-нибудь знает, что мне не хватает?

Дополнительная информация: Столбец, который я пытаюсь найти, например, column1. Если я запустил SQL-запрос с ...AND CLOUMN_NAME = 'column1' ..., я получу 1 назад. Если я печатаю переменную @column в SP, я получаю «column1». @column объявлен как входной переменной с 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, @[email protected] 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 

Если я напечатаю переменную [@column] в usp_checkColumn, я получу правильный столбец внутри '. Если я копирую &, вставьте распечатку этой переменной и вставьте ее в запрос. Я получаю 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 для всех остальных. Возможно ли, что поле с пробелом может быть проблемой? Хотя они работают, когда вы делаете это вручную. Дело не в том, что у меня действительно есть возможность изменить его, но по крайней мере теперь я буду причиной проблемы.

+3

Что означает «не ... успешно»? Вы получаете ошибку, неправильное значение, что-то еще? Вы уверены, что правильно заполнены '@ column'? Код работает отлично для меня. –

+0

Он возвращает NULL, @column является входной переменной хранимой процедуры и всегда содержит «columnName», когда я печатаю их для устранения неполадок. – nja

+1

Затем либо столбец не был найден, либо вы не заполнили '@ column'. –

ответ

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) 
+0

Большое спасибо за ваш ввод. в том, что определение t_field - это только таблица, в которой я определяю, какие поля импортируются в t_table. На самом деле поля являются частью таблицы t_sourceTable, но я думаю, что мне нужно перейти к этой теме немного по-другому и просто разработать небольшой веб-интерфейс, который делает этот импорт столбца для меня – nja

Смежные вопросы