简体   繁体   English

标量值 function 来自 SQL 从 C# 调用时服务器不返回值

[英]Scalar valued function from SQL Server not returning value when called from C#

I was given this function我得到了这个 function

CREATE FUNCTION [dbo].[GET_WEBGIS_ISSUE_NUM]
    ()
RETURNS VARCHAR(50)
AS 
BEGIN
    DECLARE @v_new_num int, @v_new_issue_num varchar(50);
    
    SET @v_new_num = (SELECT COUNT(*) + 1 
                      FROM [dbo].[WEBGIS_ISSUE] 
                      WHERE [ISSUE_NUM] LIKE  CONCAT(FORMAT(GETDATE(), 'yyMM'), '%'));

    IF @v_new_num < 10 
        SET @v_new_issue_num = CONCAT(FORMAT(GETDATE(), 'yyMM'), '00', @v_new_num);

    ELSE IF @v_new_num < 100
        SET @v_new_issue_num = CONCAT(FORMAT(GETDATE(), 'yyMM'), '00', @v_new_num);

    ELSE
        SET @v_new_issue_num = CONCAT(FORMAT(GETDATE(), 'yyMM'), @v_new_num);
    
    RETURN @v_new_issue_num 
END;

I tried calling it from the following C# code我尝试从以下 C# 代码中调用它

SqlConnection cnn = new SqlConnection(connectionString);

SqlCommand cmd = new SqlCommand();
cmd.Connection = cnn;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "[NEPS].[dbo].[GET_WEBGIS_ISSUE_NUM]";

//add any parameters the stored procedure might require
if (cmd.Connection.State == ConnectionState.Closed) //cmd.Connection.Open();
{
    cnn.Open();
    var o = cmd.ExecuteScalar();
    //blabla
    cnn.Close();
}

but when I debug the code, I kept on receiving null.但是当我调试代码时,我一直收到 null。

Notes: the connection is ok, it is connected, when I tried changing the function's name it yields an error and when I checked through the SQL Server it also returns an appropriate return value.注意:连接正常,已连接,当我尝试更改函数名称时会产生错误,当我通过 SQL 服务器检查时,它也会返回适当的返回值。

You're treating a scalar function as a Store Procedure, which is the wrong type for this type of execution.您将标量 function 视为存储过程,这是此类执行的错误类型。 You need to 'CommandType.Text' with scalar functions.您需要带有标量函数的“CommandType.Text”。

Other notes on the C# part: C#部分的其他说明:

  • use using blocks with SqlConnection and SqlCommand (let the using clause handles the dispose and close connection parts for you).使用带有SqlConnectionSqlCommandusing块(让 using 子句为您处理处置和关闭连接部分)。
  • the query should be declared as const string查询应声明为const string
  • always end the query with a semicolon (even if it's running in the SQL Server without it).始终以分号结束查询(即使它在没有它的 SQL 服务器中运行)。
  • avoid using short names, choose a readable naming for your variables.避免使用短名称,为变量选择可读的命名。

here is the C# code:这是 C# 代码:

const string query = "SELECT [NEPS].[dbo].[GET_WEBGIS_ISSUE_NUM]();";

using(SqlConnection connection = new SqlConnection(connectionString))
    using(SqlCommand command = new SqlCommand(query, connection))
    {
        connection.Open();
        var result = command.ExecuteScalar();

        // do stuff
    }

For the function GET_WEBGIS_ISSUE_NUM perhaps you can avoid the extra IF s with this line:对于 function GET_WEBGIS_ISSUE_NUM也许你可以避免额外的IF这行:

CREATE FUNCTION [dbo].[GET_WEBGIS_ISSUE_NUM]
    ()
RETURNS VARCHAR(50)
AS 
BEGIN
    DECLARE @v_new_num int, @v_new_issue_num varchar(50);
    
    SET @v_new_num = (SELECT COUNT(*) + 1 
                      FROM [dbo].[WEBGIS_ISSUE] 
                      WHERE [ISSUE_NUM] LIKE  CONCAT(FORMAT(GETDATE(), 'yyMM'), '%'));

    SET @v_new_issue_num, FORMAT(GETDATE(), 'yyMM') + RIGHT('000' + CAST(@v_new_num AS VARCHAR), 4);
    
    RETURN @v_new_issue_num 
END;

It is more common to use a SELECT statement to return a scalar function result.更常见的是使用SELECT语句返回标量 function 结果。 When you use EXECUTE (due to CommandType.StoredProcedure ), you need to also specify a return parameter and retrieve the result from the parameter after execution:当您使用EXECUTE时(由于CommandType.StoredProcedure ),您还需要指定一个返回参数并在执行后从该参数中检索结果:

var result = cmd.Parameters.Add("@result", SqlDbType.VarChar, 50);
result.Direction = ParameterDirection.ReturnValue;
cmd.ExecuteNonQuery(); //ExecuteScalar will work too but the result is null and you still need to use the parameter
var o = result.Value;

As noted in the comments to your question, consider the concurrency implications of this approach.如对您问题的评论中所述,请考虑此方法的并发含义。 Duplicate values will be returned until the row count changes.将返回重复值,直到行数更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM