2016-12-28 52 views
0

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

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]子句= @ p_bill_id不信任,现在想回SP这样的:

p_bill_id,not found 

和其他例如C#中的所有变量正确的,但两场[ p_channel_type]和[p_payment_id]不正确到where子句,但其他6字段现在正确SP返回th S:

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

问题的总结:

如果没有找到传递的参数值数据,我希望它返回相应的列。

例如:

[p_channel_type],not found 
[p_payment_id],not found 
+2

[不良习惯踢:宣布不VARCHAR(长度)](http://sqlblog.com/blogs/aaron_bertrand/archive/2009/ 10/09/bad-habits-to-kick-declaring-varchar-without-length.aspx) - 你应该总是**为任何'varchar'变量和参数提供一个长度,你使用 –

回答

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][email protected]_bank and [p_pay_date][email protected]_pay_date 
     and [p_bill_id][email protected]_bill_id and [p_payment_id][email protected]_payment_id 
     and [p_ref_code][email protected]_ref_code and [p_branch][email protected]_branch 
     and [p_channel_type][email protected]_channel_type and [p_send_date][email protected]_send_date 

END 
GO 
+0

请等待测试 –

+0

运行时出现此错误:消息50000,级别16,状态1,过程CheckValidbehzad,行18 [批处理开始行2] 未找到行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 
}