【问题标题】:How do I pass a table to a stored procedure?如何将表传递给存储过程?
【发布时间】:2014-07-30 04:53:28
【问题描述】:

我第一次尝试创建存储过程(使用 VS2012 进行编辑)我试图将我的存储过程传递给一个包含两列的表。但是,当我单击解析检查我的代码时,我收到以下错误。

消息 156,第 15 级,状态 1,第 1 行
关键字“AS”附近的语法不正确。

消息 102,级别 15,状态 1,过程 SaveMsgData,第 10 行
'READONLY' 附近的语法不正确。

消息 1087,级别 15,状态 2,过程 SaveMsgData,第 45 行
必须声明表变量“@tagList”。

我认为最后两个错误源于第一个,但我不知道是什么导致了第一个。据我所知,我的语法是正确的。

这是我的完整代码。

CREATE TYPE TagListType AS TABLE
(                     
       TagID varchar(100),                
       AntNum int
);
GO

CREATE PROCEDURE SaveMsgData 
    @Mac nvarchar(30),
    @tagList TagListType READONLY
AS
    DECLARE @ReaderID int
    DECLARE @AntList TABLE (AntennaID int, AntNum int)

    SELECT @ReaderID = -1

    SELECT @ReaderID = Id
    FROM dbo.Readers
    WHERE MAC = @Mac

    IF (@ReaderID >= 0)
    BEGIN
        INSERT INTO @AntList (AntennaID,Antnum,TargetNumOfTags) 
            SELECT id, AntennaNumber, numOfTags 
            FROM Antennae
            WHERE ID = @ReaderID

        DECLARE @count int
        DECLARE @len int                    

        SET @count = 0
        SET @len = 0

        WHILE @count <= @len
        BEGIN
            DECLARE @LocalAnt int
            DECLARE @LocalTarget int
            DECLARE @LocalAntID int
            DECLARE @LocalStatus int
            DECLARE @LocalTagsRead int

            SELECT @LocalAnt = Antnum, @LocalTarget = TargetNumOfTags, @LocalAntID = AntID 
            FROM #AntList 
            WHERE Antnum = @count

            SELECT @LocalTagsRead = COUNT(*) FROM @tagList WHERE AntNum = @count

            IF @LocalTagsRead = @LocalTarget
            BEGIN
                SET @LocalStatus = 0
            END
        ELSE
            BEGIN
                SET @LocalStatus = 1
            END

        INSERT INTO Readings 
        VALUES (@LocalStatus, @LocalTarget, @LocalTagsRead, CURRENT_TIMESTAMP, @LocalAntID, @ReaderID)

        --Will insert Tags in to tag table here later.
        SET @count = @count + 1
    END
END
GO

这里的目的是让我的 C# 桌面应用程序使用这个存储过程。

【问题讨论】:

    标签: sql-server tsql stored-procedures


    【解决方案1】:

    表值参数自 SQL Server 2008 起可用 - 从错误消息来看,您很可能没有在 2008 实例上运行...。

    您真的在使用 2008 年或更新的服务器引擎吗?

    对您的服务器使用SELECT @@VERSION 找出答案 - 它会报告什么?

    【讨论】:

    • ..... 掌心 我还在 2005 年,我们的 IT 经理计划很快升级到 2012 年。出于某种原因,我以为他已经把我的数据库移过来了。
    • 只是一个更新。我在我的半流氓虚拟机上安装了 SQL Server 2012 Express,并用它解析了我的代码,它解析得很好。因此,我的项目重回正轨,IT 经理可以在完成时将我的主数据库迁移过来。
    【解决方案2】:

    您可以传递一个 CSV 参数并使用此函数将其转换为 XML:

    create function udf_CsvToXML(@Csv as varchar(4096),@Delim as varchar(15)=',')
    returns xml
    as
    begin
        declare @xml as xml = CAST('<XML>'+('<X>'+REPLACE(@Csv,@Delim,'</X><X>')+'</X></XML>') AS XML)
        return @xml
    end
    

    然后,您可以在连接或其他任何内容中使用 XML,就好像它是一个表一样:

    DECLARE @TitlesXML as XML = dbo.udf_CsvToXML(@Titles,',')
    select distinct t
    from p
    join    (SELECT N.value('.[1]', 'varchar(25)') as value FROM @TitlesXML.nodes('/XML/X') as T(N)) tt
        on tt.value = p.t
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-09
      • 2014-06-11
      • 2011-07-13
      • 1970-01-01
      • 2012-09-01
      • 1970-01-01
      • 2011-10-23
      相关资源
      最近更新 更多