如何在存储过程中实现此T-SQL?

时间:2016-12-28 07:51:21

标签: sql-server tsql

我是SQL Server的新手,想要实现这个场景。我的存储过程从C#Web应用程序获取8个输入参数,并检查所有输入是否已进入表中。为此,我编写了这个简单的存储过程:

CREATE PROCEDURE CheckValid 
    @p_bank varchar,
    @p_pay_date varchar,
    @p_bill_id varchar,
    @p_payment_id varchar,
    @p_ref_code varchar,
    @p_branch varchar,
    @p_channel_type varchar,
    @p_send_date varchar
AS
BEGIN
    SELECT  
        [p_bank], [p_pay_date], [p_bill_id], [p_payment_id],
        [p_ref_code], [p_branch], [p_channel_type], [p_send_date]
    FROM 
        [SAMPLE].[dbo].[MixedTable]
    WHERE
         [p_bank] = @p_bank 
         AND [p_pay_date] = @p_pay_date 
         AND [p_bill_id] = @p_bill_id 
         AND [p_payment_id] = @p_payment_id 
         AND [p_ref_code] = @p_ref_code 
         AND [p_branch] = @p_branch 
         AND [p_channel_type] = @p_channel_type 
         AND [p_send_date] = @p_send_date
END

但是想要返回c#应用程序这个场景,例如c#发送所有字段但是当存储过程选择为此目的运行时找不到数据,例如p_bill_id不正确进入表中以获取更多解释查询[p_bill_id]中的where子句= @ p_bill_id不信任,现在想要返回sp:

p_bill_id,not found

和其他示例c#所有变量都正确,但是两个字段[p_channel_type]和[p_payment_id]不正确进入where子句但其他6个字段正确现在SP返回此:

[p_channel_type],not found
[p_payment_id],not found

问题摘要:

当找不到传递参数值的数据时,我希望它返回相应的列。

例如:

[p_channel_type],not found   
[p_payment_id],not found

2 个答案:

答案 0 :(得分:1)

注意,varchar表示varchar(1),因此您应明确指定每个参数的长度,例如varchar(100)

CREATE PROCEDURE CheckValid
    @p_bank varchar(<length>),
    @p_pay_date varchar(<length>),
    @p_bill_id varchar(<length>),
    @p_payment_id varchar(<length>),
    @p_ref_code varchar(<length>),
    @p_branch varchar(<length>),
    @p_channel_type varchar(<length>),
    @p_send_date varchar(<length>)
AS
BEGIN
    if not exists(select 1 from dbo.BankTable where p_bank = @p_bank)
    begin
        raiserror('Bank %s not found', 16, 1, @p_bank)
        return
    end

    if not exists(select 1 from dbo.BillTable where p_bill_id = @p_bill_id)
    begin
        raiserror('Bill %s not found', 16, 1, @p_bill_id)
        return
    end

    ...

    SELECT  [p_bank],[p_pay_date],[p_bill_id],[p_payment_id],[p_ref_code],[p_branch],[p_channel_type],[p_send_date]
    FROM [SAMPLE].[dbo].[MixedTable]
    where [p_bank]=@p_bank and [p_pay_date]=@p_pay_date 
        and [p_bill_id]=@p_bill_id and [p_payment_id]=@p_payment_id 
        and [p_ref_code]=@p_ref_code and [p_branch]=@p_branch 
        and [p_channel_type]=@p_channel_type and [p_send_date]=@p_send_date

END
GO

答案 1 :(得分:0)

而不是为此移动“验证”逻辑创建存储过程到您的c#应用程序 数据库只是IO设备,我认为在IO设备中保持“业务逻辑”不是一个好方法。

// Class which represent your eight parameters
public class Data
{
    public string Bank { get; set; }
    public string PayDate { get; set; }
    public string BillId { get; set; }
    public string PaymentId { get; set; }
    public string RefCode { get; set; }
    public string Branch { get; set; }
    public string ChannelType  { get; set; }
    public string SendDate { get; set; }
}

public class Validation
{
    private Data _data;

    public Validation(Data data)
    {
        _data = data;
    }

    public IEnumerable<string> Validate()
    {
        var columns = new KeyValuePair<string, string>[]
        {
            new KeyValuePair("p_bank", _data.Bank),
            new KeyValuePair("p_pay_date", _data.PayDate), 
            new KeyValuePair("p_bill_id", _data.BillId), 
            new KeyValuePair("p_payment_id", _data.PaymentId),
            new KeyValuePair("p_ref_code], _data.RefCode), 
            new KeyValuePair("p_branch", _data.Branch), 
            new KeyValuePair("p_channel_type", _data.ChannelType), 
            new KeyValuePair("p_send_date", _data.SendDate)
        };

        return columns.Where(pair => IsValueExists(pair.Key, pair.Value) == false);
    }

    private bool IsValueExists(string columnName, string value)
    {
        var query = 
            $"SELECT [{columnName}]
              FROM [SAMPLE].[dbo].[MixedTable]
              WHERE [{columnName}] = @value";

        var parameter = new SqlParameter 
        { 
            ParameterName = "@value", 
            SqlDbType = SqlDbType.VarChar,
            Value = _data.Bank 
        };

        using (var connection = new SqlConnection(yourConnectionString))
        using (var command = new SqlCommand(query, connection))
        {
            command.Parameters.Add(parameter);
            connection.Open();
            var value = command.ExecuteScalar();
            return value != null; // null returned if no rows exists
        }
    }
}

然后你可以在某个地方使用这个方法

var data = new Data { Bank = "BankName", RefCode = "SomeRefcode" } // put all values
var validation = new Validation(data);
var invalidValues = validation.Validate();

foreach(var invalidValue in invalidValues)
{
    // Print or save column names where value is invalid
}