【问题标题】:SQL Server stored procedure with user-defined table type具有用户定义表类型的 SQL Server 存储过程
【发布时间】:2021-11-04 08:35:32
【问题描述】:

我在 SQL Server 中有一个带有参数 @Files 的存储过程,它是用户定义的表类型。从 C# 代码执行时出现错误:

System.Data.SqlClient.SqlException: '传入的表格数据流 (TDS) 远程过程调用 (RPC) 协议流不正确。表值参数 3 ("@Files"),第 0 行,第 0 列:数据类型 0xF3(用户定义的表类型)具有指定的非零长度数据库名称。数据库名称不允许与表值参数一起使用,只有模式名称和类型名称有效。'

这是我的 C# 代码:

DataTable dt = new DataTable();
dt.Columns.Add("ComputerId", typeof(int));
dt.Columns.Add("FolderId", typeof(int));
dt.Columns.Add("FilePath", typeof(string));
dt.Columns.Add("FileName", typeof(string));
dt.Columns.Add("Size", typeof(long));
dt.Columns.Add("LastWriteTimeUtc", typeof(DateTime));
dt.Columns.Add("ReadOnly", typeof(bool));

foreach (var item in listFileInformation)
{
    dt.Rows.Add(1, 1, item.FilePath, item.FileName, item.Size, item.LastWriteUTC, item.ReaddOnly);
}

databaseHelper.AddParameter("@ComputerId", 1);
databaseHelper.AddParameter("@FolderId", 1);

SqlParameter tableTypeParam = new SqlParameter("@Files", SqlDbType.Structured)
                                  {
                                      TypeName = "Inbox.dbo.EngComputerFileTableType",
                                      Value = dt
                                  };
databaseHelper.AddParameter(tableTypeParam);

databaseHelper.ExecuteNonQuery("InsertEngComputerFiles", System.Data.CommandType.StoredProcedure, System.Data.ConnectionState.Open);

databaseHelper.connection.Close();

这是存储过程:

CREATE PROCEDURE [dbo].[InsertEngComputerFiles]
    @ComputerId BIGINT,
    @FolderId BIGINT,
    @Files [dbo].[EngComputerFileTableType] READONLY
AS
BEGIN
    SET NOCOUNT ON;

    INSERT INTO
        [Inbox].[dbo].[EngComputerFile] (
            [ComputerId], [FolderId], [FilePath], [FileName],
            [Size], [LastWriteTimeUtc], [ReadOnly])
        SELECT
            @ComputerId, @FolderId, [FilePath], [FileName],
            [Size], [LastWriteTimeUtc], [ReadOnly]
        FROM
            @Files;

    UPDATE [Inbox].[dbo].[EngComputer]
    SET [LastScanTimeStampUtc] = SYSUTCDATETIME()
    WHERE [ComputerId] = @ComputerId;
END

【问题讨论】:

  • 你为什么说TypeName = "Inbox.dbo.EngComputerFileTableType" 而不是TypeName = "dbo.EngComputerFileTableType"?该类型必须与您调用的存储过程在同一个数据库中才能正常工作,因此数据库前缀是不必要的(错误消息告诉您它不仅不必要而且无效)。
  • @AaronBertrand 感谢您的回复!但是我已经尝试过 dbo.EngComputerFileTableType 但它也给出了错误'Invalid object name 'Inbox.dbo.EngComputerFile'。'
  • dbo.EngComputerFile dbo.EngComputerFileTableType @MiralShah .
  • @Larnu 是真的!!!
  • 不要在没有很好理由的情况下使用三部分名称。您的连接应确定数据库上下文。随着数据库在环境之间迁移,这些数据库的名称经常发生变化。使用 3 部分名称只会创建更多工作来支持这种非常常见的做法。

标签: c# sql-server stored-procedures ado.net


【解决方案1】:

消息说明一切 你需要改变这一行

SqlParameter tableTypeParam = new SqlParameter("@Files", SqlDbType.Structured)
{
//TypeName = "Inbox.dbo.EngComputerFileTableType",
TypeName = "dbo.EngComputerFileTableType",

Value = dt
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-24
    • 2017-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多