【问题标题】:SQL Server dynamic parameters join stored procedureSQL Server 动态参数加入存储过程
【发布时间】:2015-04-24 01:04:42
【问题描述】:

这是我的存储过程和参数,但我需要进行动态搜索

SELECT
  dbo.Invoices.*, 
  dbo.Vessels.Name AS VesselName, 
  dbo.Companies.Name AS CompanyName,
  dbo.InvoiceTypes.Name AS InvoiceTypeName, 
  dbo.InvoiceItems.Name AS InvoiceItemName, 
  dbo.InvoiceItems.InvoiceItemID
FROM            
  dbo.Invoices 
  LEFT JOIN dbo.Vessels ON 
    dbo.Invoices.VesselID = dbo.Vessels.VesselID 
  INNER JOIN dbo.Companies ON 
    dbo.Invoices.CompanyID = dbo.Companies.CompanyID 
  LEFT JOIN dbo.InvoiceTypes ON 
    dbo.Invoices.InvoiceTypeID = dbo.InvoiceTypes.InvoiceTypeID 
  LEFT JOIN dbo.InvoiceVsInvoiceItems ON 
    dbo.Invoices.InvoiceID = dbo.InvoiceVsInvoiceItems.InvoiceID 
  LEFT JOIN dbo.InvoiceItems ON 
    dbo.InvoiceVsInvoiceItems.InvoiceItemID = dbo.InvoiceItems.InvoiceItemID

参数

@InvoiceItemID int,
@InvoiceTypeID int,
@VesselID int,
@PaidByID int,
@InvoiceNo NVarchar(50),
@CompanyID int,
@chkSearchInvoiceDate bit,
@chkSearchIsDueDate bit,
@chkSearchIsPaid bit,
@chkSearchReceived bit,
@chkSearchAmount bit,
@chkSearchInvoiceType bit,
@InvoiceFromDate    DateTime,
@InvoiceToDate    DateTime,
@FromDueDate    DateTime,
@ToDueDate     DateTime, 
@FromAmount decimal(18,4),
@ToAmount decimal(18,4)    

但是我试过了,当有多个where时我该怎么办?我不能:(

谢谢

Declare @SQLQuery AS NVarchar(4000)
Declare @ParamDefinition AS NVarchar(2000)    
Set @SQLQuery = 'SELECT dbo.Invoices.*, dbo.Vessels.Name AS VesselName, dbo.Companies.Name AS CompanyName, dbo.InvoiceTypes.Name AS InvoiceTypeName, 
                 dbo.InvoiceItems.Name AS InvoiceItemName, dbo.InvoiceItems.InvoiceItemID' 

If @InvoiceItemID Is Not Null
     Set @SQLQuery = @SQLQuery + 'FROM dbo.Invoices LEFT JOIN  dbo.InvoiceItems ON dbo.InvoiceVsInvoiceItems.InvoiceItemID = dbo.InvoiceItems.InvoiceItemID WHERE dbo.InvoiceVsInvoiceItems.InvoiceItemID = @InvoiceItemID'

If @VesselID Is Not Null
     Set @SQLQuery = @SQLQuery + 'LEFT JOIN  dbo.Vessels ON dbo.Vessels.VesselID = dbo.Invoices.VesselID WHERE dbo.Invoices.VesselID = @VesselID'

If @InvoiceNo Is Not Null
     Set @SQLQuery = @SQLQuery + 'WHERE dbo.Invoices.InvoiceNo = @InvoiceNo'

If @CompanyID Is Not Null
     Set @SQLQuery = @SQLQuery + 'WHERE dbo.Invoices.CompanyID = @CompanyID'

If @chkSearchInvoiceDate >  0
     Set @SQLQuery = @SQLQuery + 'WHERE Between @InvoiceFromDate and @InvoiceToDate'

If @chkSearchIsDueDate >  0
     Set @SQLQuery = @SQLQuery + 'WHERE Between @FromDueDate and @ToDueDate'

If @chkSearchIsPaid >  0
     Set @SQLQuery = @SQLQuery + 'WHERE dbo.Invoices.PaidBy = @PaidBy'

If @chkSearchReceived >  0
      Set @SQLQuery = @SQLQuery + 'WHERE dbo.Invoices.InvoiceNo = @InvoiceNo'

【问题讨论】:

    标签: sql sql-server stored-procedures dynamic


    【解决方案1】:

    如果您希望能够在where 子句中同时使用多个参数,您可以像这样添加它们:

    Declare @SQLQuery AS NVarchar(4000)
    Declare @ParamDefinition AS NVarchar(2000)    
    Set @SQLQuery = '
    SELECT 
        dbo.Invoices.*, 
        dbo.Vessels.Name AS VesselName, 
        dbo.Companies.Name AS CompanyName, 
        dbo.InvoiceTypes.Name AS InvoiceTypeName, 
        dbo.InvoiceItems.Name AS InvoiceItemName, 
        dbo.InvoiceItems.InvoiceItemID
    FROM dbo.Invoices 
    LEFT JOIN dbo.InvoiceItems ON dbo.InvoiceVsInvoiceItems.InvoiceItemID = dbo.InvoiceItems.InvoiceItemID
    LEFT JOIN dbo.Vessels ON dbo.Vessels.VesselID = dbo.Invoices.VesselID 
    WHERE 1=1 ' 
    
    If @InvoiceItemID Is Not Null
        Set @SQLQuery = @SQLQuery + ' AND dbo.InvoiceVsInvoiceItems.InvoiceItemID = @InvoiceItemID'
    
    If @VesselID Is Not Null
        Set @SQLQuery = @SQLQuery + ' AND dbo.Invoices.VesselID = @VesselID'
    
    If @InvoiceNo Is Not Null
        Set @SQLQuery = @SQLQuery + ' AND dbo.Invoices.InvoiceNo = @InvoiceNo'
    
    If @CompanyID Is Not Null
        Set @SQLQuery = @SQLQuery + ' AND dbo.Invoices.CompanyID = @CompanyID'
    
    If @chkSearchInvoiceDate >  0
        Set @SQLQuery = @SQLQuery + ' AND InvoiceDate Between @InvoiceFromDate and @InvoiceTODate'
    
    If @chkSearchIsDueDate >  0
        Set @SQLQuery = @SQLQuery + ' AND IsDueDate Between @FromDueDate and @ToDueDate'
    
    If @chkSearchIsPaid >  0
        Set @SQLQuery = @SQLQuery + ' AND dbo.Invoices.PaidBy = @PaidByID'
    
    If @chkSearchReceived >  0
        Set @SQLQuery = @SQLQuery + ' AND dbo.Invoices.InvoiceNo = @InvoiceNo'
    

    【讨论】:

    • 真的需要为@VesselID 强制转换吗?
    • @JamesZ 我认为需要能够连接字符串和整数。注入的所有其他参数也是如此。
    • 是我看错了还是你编辑了这个...我认为变量应该在 SQL 文本中,而不是分别提供给 sp_execute_sql 的值和值?
    • 我建议使用带有变量的 sp_execute_sql,否则有可能发生 SQL 注入和缓存膨胀
    • @JamesZ 哦,对,我确实看错了。已编辑。误会了应该是params来执行sql
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-26
    • 2019-03-17
    相关资源
    最近更新 更多