C# (.NET 4.5、Visual Studio 2013) から proc を呼び出すと、sp_executesql を使用してテーブル変数が渡されます。ただし、SQL Server (2008 Std、2008 Ent、および 2012 Std でテスト済み) は、これを空のテーブルとして渡します。
ここにある 3 つのステートメントは同じ結果を返すと思いますが、最後のステートメントはそうではありません。
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',@testTable=@x
--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
私にとっての明白な答えは、proc 内のテーブル変数で 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");
}
}
あなたが私に与えることができるどんな助けでも大歓迎です. ありがとう!!!