Вызов proc из C# (.NET 4.5, Visual Studio 2013), он передает переменные таблицы, используя sp_executesql. Однако SQL Server (протестированный в 2008 Std, 2008 Ent и 2012 Std) проходит через пустую таблицу.Передача переменной таблицы с C# на SQL Server проходит пустую таблицу
Я бы ожидал, что три утверждения здесь возвратят те же результаты, но последний не будет.
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[_testproc]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[_testproc]
GO
IF EXISTS (SELECT * FROM sys.types st JOIN sys.schemas ss ON st.schema_id = ss.schema_id WHERE st.name = N'testType' AND ss.name = N'dbo')
DROP TYPE [dbo].[testType]
GO
--------------------------------
CREATE TYPE [dbo].[testType] AS TABLE(
[ServerID] [int] NULL
, [Field2] int NOT NULL
)
GO
---------------------------------
CREATE PROC _testproc
@testTable testType READONLY
AS
SELECT * FROM @testTable
GO
---------------------------------
declare @x testtype
INSERT INTO @X values (1,2)
INSERT INTO @X values (3,4)
--Begin Three calls that should return the same result
--Query the table directly
SELECT * FROM @x
--Call it the way I would through t-sql
exec _testproc @testTable = @x
--Call it the way C# in Visual Studio 2013 calls it
exec sp_executesql N'dbo._testproc',N'@testTable [dbo].[TestType] READONLY',@[email protected]
--Cleanup
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[_testproc]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[_testproc]
GO
IF EXISTS (SELECT * FROM sys.types st JOIN sys.schemas ss ON st.schema_id = ss.schema_id WHERE st.name = N'testType' AND ss.name = N'dbo')
DROP TYPE [dbo].[testType]
GO
Очевидным ответом мне было бы не использовать sp_executesql со столом переменных в прок, но это C# код делает именно это.
using (SqlCommand cmd = new SqlCommand("dbo._testproc", connCentral))
{
SqlParameter sqlpTestTable = cmd.Parameters.AddWithValue("@TestTable", dtTestTable);
sqlpTestTable.SqlDbType = SqlDbType.Structured;
sqlpTestTable.TypeName = "dbo.TestType";
using (SqlDataAdapter aTest = new SqlDataAdapter())
{
aTest.SelectCommand = cmd;
aTest.Fill(dsTest2, "Test2");
}
}
Любая помощь, которую вы можете мне дать, была бы весьма признательна. Благодаря!!!
Это работает как с SQL Server, так и с .NET, и спасибо. Однако я бы добавил, что это не так, как вы обычно передаете параметры из кода .NET. На данный момент мне кажется, что я использую обходное решение вместо правильного кода, хотя я очень рад этому! используя (SqlCommand cmd = новый SqlCommand ("dbo._testproc @testTable", connCentral)) –