sp_executesql在从C#传递数据表到SQL Server时创建问题

huangapple go评论63阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2023年7月10日 20:30:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76653771.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定