英文:
sp_executesql creating issue when passing a data table from C# to SQL Server
问题
我一直在尝试将 DataTable 从 C# 发送到 SQL Server。我们已经将问题缩小到在 SQL Server 中执行代码。
以下是测试代码的设置:
DROP PROCEDURE [dbo].[yy_StoredProc]
GO
DROP TYPE [dbo].[DataTableType2]
GO
CREATE TYPE [dbo].[DataTableType2] AS TABLE
(
[Street] [varchar](100) NULL,
[City] [varchar](100) NULL,
[State] [varchar](100) NULL,
[Country] [varchar](100) NULL
)
GO
CREATE PROCEDURE [dbo].[yy_StoredProc]
@PassedMvcTable DataTableType2 READONLY
AS
BEGIN
SELECT * FROM @passedMvcTable
END
GO
下面的代码是基于我们从 Profiler 检索到的代码进行建模的。输出 #1 和输出 #3 返回 @p3 中的数据。然而,输出 #2 不返回任何数据。
为什么输出 #1 和输出 #3 能工作,但输出 #2 不能?
declare @p3 DataTableType2
insert into @p3 values('International Dr', 'Orlando', 'FL', 'USA')
--OUTPUT #1
select * from @p3
--OUTPUT #2
exec sp_executesql N'EXEC yy_StoredProc',
N'@PassedMvcTable [DataTableType2] READONLY',
@passedMvcTable=@p3
--OUTPUT #3
exec yy_StoredProc @passedMvcTable=@p3
英文:
I have been trying to send a DataTable from C# to SQL Server. We have narrowed down the problem to execution of code in SQL Server.
Below is the setup for the testing code developed.
DROP PROCEDURE [dbo].[yy_StoredProc]
GO
DROP TYPE [dbo].[DataTableType2]
GO
CREATE TYPE [dbo].[DataTableType2] AS TABLE
(
[Street] [varchar](100) NULL,
[City] [varchar](100) NULL,
[State] [varchar](100) NULL,
[Country] [varchar](100) NULL
)
GO
CREATE PROCEDURE [dbo].[yy_StoredProc]
@PassedMvcTable DataTableType2 READONLY
AS
BEGIN
SELECT * FROM @passedMvcTable
END
GO
The code below is modeled after that we retrieved with Profiler. Output #1 and Output #3 return the data in @p3. However, Output #2 does not return any data.
Why do outputs #1 and #3 work, but output #2 doesn’t?
declare @p3 DataTableType2
insert into @p3 values('International Dr', 'Orlando', 'FL', 'USA')
--OUTPUT #1
select * from @p3
--OUTPUT #2
exec sp_executesql N'EXEC yy_StoredProc',
N'@PassedMvcTable [DataTableType2] READONLY',
@passedMvcTable=@p3
--OUTPUT #3
exec yy_StoredProc @passedMvcTable=@p3
答案1
得分: 3
只需将参数传递给该存储过程即可:
exec sp_executesql
N'EXEC yy_StoredProc @PassedMvcTable',
N'@PassedMvcTable DataTableType2 READONLY',
@passedMvcTable=@p3
英文:
You're simply missing passing the parameter to the procedure:
exec sp_executesql
N'EXEC yy_StoredProc @PassedMvcTable',
N'@PassedMvcTable DataTableType2 READONLY',
@passedMvcTable=@p3
答案2
得分: 1
我无法看到你的C#代码,但你几乎肯定是在错误地创建命令。
你需要使用CommandType.StoredProcedure
来创建它,只需传递存储过程的名称,而不是EXEC...
。
using var conn = new SqlConnection(ConnStringHere);
using var comm = new SqlCommand("dbo.yy_StoredProc", conn);
comm.CommandType = CommandType.StoredProcedure;
comm.Parameters.Add(new SqlParameter("@PassedMvcTable", SqlDbType.Structured)
{
TypeName = "dbo.DataTableType2",
Value = GetDataTableForTVPHere(),
});
using var reader = comm.ExecuteReader();
// 等等
请注意,分析器对于对 TVP(表值参数)的 INSERT
语句显示的内容实际上并不是这样发生的。它只是对底层发生的事情的文本表示。
英文:
I can't see your C# code, but you are almost certainly creating the command incorrectly.
You need to create it with CommandType.StoredProcedure
and just pass the name of the procedure, not EXEC...
using var conn = new SqlConnection(ConnStringHere);
using var comm = new SqlCommand("dbo.yy_StoredProc", conn);
comm.CommandType = CommandType.StoredProcedure;
comm.Parameters.Add(new SqlParameter("@PassedMvcTable", SqlDbType.Structured)
{
TypeName = "dbo.DataTableType2",
Value = GetDataTableForTVPHere(),
});
using var reader = comm.ExecuteReader();
// etc
Note that what the profiler shows for INSERT
statements into the TVP doesn't actually happen like that. It's just a text representation of what's going on under the hood.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论