SQL Server 存储过程只返回临时表的最后一行

Posted

技术标签:

【中文标题】SQL Server 存储过程只返回临时表的最后一行【英文标题】:SQL Server stored procedure only returns last row of temporary table 【发布时间】:2021-07-22 07:52:18 【问题描述】:

几周前我的所有代码都达到了预期目的,尽管我认为我不小心删除了一些东西,现在它不能正常工作。存储过程假定返回多行数据,每行包含TopicIDTopicNamePercentComplete 列。

在 JSONController / API 中,数据应该被连接成一个单一的字符串,其中每列用# 分隔,而每行用| 分隔。

例子:

"4#Ideology#50|5#Morality#100|6#Religion#0"

我现在注意到的是存储过程只返回最后一行,所以在这个例子中是“6#Religion#0”。

是我遗漏了代码,还是我做错了什么?同样在 JSONController/API 中,如何根据从存储过程返回的行数进行连接?

存储过程代码:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[getTopicsForSubject]
    @SubjectID int,
    @StudentID int
AS
BEGIN
    CREATE TABLE #SubjectTopics
    (
        TopicID int,
        Topic varchar(1000),
        PercentComplete int
    )

    INSERT INTO #SubjectTopics
        SELECT TopicID, topic, 0 
        FROM topic
        WHERE SubjectID = @SubjectID

    UPDATE #SubjectTopics
    SET PercentComplete = ISNULL((SELECT PercentComplete FROM StudentTopic
                                  WHERE topicid = #SubjectTopics.TopicID
                                    AND StudentID = @StudentID), 0)

    SELECT * FROM #SubjectTopics
    RETURN

    DROP TABLE #SubjectTopics
END

API / JSON 控制器代码:

private static string ExecuteSPGetSubjectsData(string queryString, string subjectID, string studentID)

    string json = "";
    string connectionString = ConfigurationManager.AppSettings["dbconn"].ToString();

    using (SqlConnection conn = new SqlConnection(connectionString))
    
        conn.Open();

        // 1.  create a command object identifying the stored procedure
        SqlCommand cmd = new SqlCommand(queryString, conn);

        // 2. set the command object so it knows to execute a stored procedure
        cmd.CommandType = CommandType.StoredProcedure;

        // 3. add parameter to command, which will be passed to the stored procedure
        cmd.Parameters.Add(new SqlParameter("@SubjectID", subjectID));
        cmd.Parameters.Add(new SqlParameter("@StudentID", studentID));

        // execute the command
        using (SqlDataReader rdr = cmd.ExecuteReader())
        
            // iterate over the results, printing each to console
            while (rdr.Read())
            
                json = (string)rdr[0].ToString() + "#" + (string)rdr[1].ToString() + "#" + (string)rdr[2].ToString() + "|";
            
        
    

    return json;

【问题讨论】:

您的“json = (string)rdr[0] .....”代码行只是替换“json”变量,因为“rdr.Read()”循环遍历每条记录。而不是“json =(string).....”,你会想要“json +=(string)......” - 每次都会附加到“json”变量,而不是替换它 【参考方案1】:

您需要将每条记录的值附加(+=,而不仅仅是 =)到您的“json”变量 - 目前,您的代码行正在替换“json”变量值,因为它循环遍历每条记录(这说明为什么最终结果的值来自最后一条记录)

while (rdr.Read())

    json += (string)rdr[0].ToString() + "#" + (string)rdr[1].ToString() + "#" + (string)rdr[2].ToString() + "|";

【讨论】:

以上是关于SQL Server 存储过程只返回临时表的最后一行的主要内容,如果未能解决你的问题,请参考以下文章

SQL SERVER里面如何在存储过程里面获取另一个存储过程所返回的表的数据?

SQL Server 导入和导出向导在使用临时表的存储过程中给出无效对象错误

有没有办法获取 SQL Server 中所有当前临时表的列表?

sql server中怎么把一个表的数据全部插入到另一个表,每次1000条的插入,一次执行,不要在存储过程里改的

关于sqlserver临时表的问题,请教高手!

我用sqlserver写好了一个存储过程 怎么样才能返回出一个搜索语句的结果集给c#