Использование ExecuteNonQuery для запуска хранимой процедуры не создает мою таблицу, но таблица создается при выполнении sp в SSMS

Некоторые примечания:

  1. ExecuteNonQuery возвращает -1
  2. ExecuteNonQuery удалит таблицу (@droptable), но не создаст новую таблицу (@code)
  3. длина запроса @code составляет 10265 символов.
  4. Хранимая процедура отлично работает в SSMS и возвращает 22 строки в таблице.

Есть ли какие-либо идеи относительно того, почему функция C# ExecuteNonQuery не выполняет часть хранимой процедуры exec(@code)?

ALTER procedure [dbo].[sp_create_EditControlResultsPivot] 
as
begin
    declare @t nvarchar (250); 
    set @t = 'editControlResults'

    declare @newtable nvarchar(250); 
    set @newtable = 'dbo.' + @t + 'Pivot'

    declare @nonPivotColumn1 nvarchar(250); 
    set @nonPivotColumn1 = 'num'

    declare @nonPivotColumn2 nvarchar(25); 
    set @nonPivotColumn2 = 'File_Name'

    declare @droptable nvarchar(max); 
    set @droptable =  
'if EXISTS (select * from sys.objects where object_id = object_id(N''' + @newtable + '''))
begin drop table ' + @newtable + ' end
'

    declare @i int 
    set @i = 1;

    declare @itemList nvarchar(max);
    declare @code nvarchar(max);

    while @i <= (
        select COUNT(*) 
        from sys.columns c 
        left join sys.tables t on c.object_id = t.object_id 
        where 1=1 
          and c.name not like @nonPivotColumn1 
          and c.name not like @nonPivotColumn2
          and t.name = @t
    ) 
    begin

    set @itemList = @itemList + ', ' +
    (
        select col from 
        (
            select c.name as col, ROW_NUMBER () over (order by c.name) as num from
            sys.columns c left join sys.tables t on c.object_id = t.object_id 
            where 1=1
            and c.name not like @nonPivotColumn1
            and c.name not like @nonPivotColumn2
            and t.name = @t 
        ) sub where num = @i
    )
    set @i = @i + 1
  end

  set @itemList = (select substring(@itemList, 2, LEN(@itemList)))

  set @code = '
  SELECT ' + @nonpivotcolumn2 + ', Item
  into ' + @newtable + '
FROM
(SELECT ' + @nonpivotcolumn2 + ', ' + @itemList + '
FROM ' + @t + ') sub
UNPIVOT
(Value FOR Item IN (' + @itemList + ')
) AS sub
where Value = ''true''
'

exec(@droptable)
exec(@code);
--print(len(@code))
END
--exec sp_create_EditControlResultsPivot

person Brian Hartigan    schedule 23.06.2015    source источник
comment
Где соответствующий код С#?   -  person sstan    schedule 23.06.2015
comment
NonQuery означает не Query, а значит, не SELECT   -  person John Saunders    schedule 23.06.2015
comment
Примечание: вы не должны не использовать префикс sp_ для своих хранимых процедур. Microsoft зарезервировала этот префикс для собственного использования ( см. Именование хранимых процедур), и вы рискуете столкнуться с конфликтом имен в будущем. Это также плохо сказывается на производительности ваших хранимых процедур. Лучше просто избегать sp_ и использовать в качестве префикса что-то другое - или вообще не использовать префикс!   -  person marc_s    schedule 23.06.2015
comment
Нет префикса лучше. По крайней мере, нет префикса, обозначающего хранимую процедуру. Вы узнаете, что это хранимая процедура, потому что CREATE PROCEDURE в ее начале. Вам не понадобится префикс, чтобы сказать вам это.   -  person John Saunders    schedule 23.06.2015
comment
Очень ценю. В случае, если это неясно, запрос @code является выбором в   -  person Brian Hartigan    schedule 23.06.2015
comment
@BrianHartigan Откуда вы знаете, что запрос @droptable выполняется? Означает ли это, что вы видели там таблицу после запуска в SSMS, затем вы запускаете через C#, а затем выполнение SELECT для этой таблицы в SSMS дает ошибку, что таблицы больше не существует? Если вы хотите увидеть, был ли усечен запрос @code, почему бы вам не добавить следующее прямо над строкой EXEC(@code): SELECT @code AS [query] INTO tempdb.dbo.CodeQuery;. Затем запустите через С#. Затем запустите SELECT * FROM tempdb.dbo.CodeQuery; в SSMS.   -  person Solomon Rutzky    schedule 23.06.2015


Ответы (2)


Метод ExecuteNonQuery возвращает количество затронутых строк, используя вместо этого метод ExecuteReader.

Метод SqlCommand.ExecuteReader

Единственный способ вернуть данные из ExecuteNonQuery — через выходной параметр.

person Ricky G    schedule 23.06.2015
comment
@code не возвращает данные, а выполняет выборку в Мои извинения за то, что не сделал это более понятным. - person Brian Hartigan; 23.06.2015

Я подозреваю ваш комментарий № 3. длина запроса @code составляет 10265 символов... может быть проблемой... я думаю, что вызов из С# обрезает его до 4000 или 8000 символов...

Поскольку вы не ожидаете набора результатов, ExecuteNonQuery подходит.

Что попробовать:

  1. Попробуйте вставить содержимое переменной @code (внутри процедуры) в таблицу и посмотрите, получаете ли вы правильный sql... как при выполнении из SSMS, так и при вызове С#

  2. Если вы получите действительный SQL-запрос на шаге 1 (в чем я сомневаюсь)... попробуйте выполнить этот запрос в SSMS, чтобы увидеть, действительно ли он работает...

person SKG    schedule 23.06.2015
comment
Похоже, он ожидает набора результатов. Вот что он имеет в виду, когда говорит, что моя таблица возвращается, когда я выполняю sp в ssms. - person John Saunders; 23.06.2015
comment
Очень признателен. Запрос @code на самом деле является выбором, и выполнение хранимой процедуры в SSMS создает 22-строчную таблицу в базе данных, как и ожидалось. ‹br› Название этого вопроса не совсем ясно. - person Brian Hartigan; 23.06.2015
comment
@ Джон ... он уже дал нам свой запрос ... мы можем сделать из него вывод, и нам не нужно полагаться на то, насколько семантически хорош его формальное утверждение ... ура ... - person SKG; 23.06.2015