【问题标题】:How to make sub queries with success with multiple parameter如何使用多个参数成功进行子查询
【发布时间】:2021-11-09 14:20:31
【问题描述】:

我有两张桌子PA_LedgerPA_Trans。我刚刚写了一个存储过程,它可以过滤日期、内部连接、按PA_Ledger.Name 分组并按该名称排序。

我有一个存储过程,可以通过加入、分组和日期过滤器查找记录,如下所示:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

-- =============================================
-- Author:      Shalin Gajjar
-- Create date: 27/10/221
-- Description: get all report data
-- =============================================
--exec [dbo].[PA_Report_IndexPagingData] 100,1,'Oct  28 2021 12:00AM','Oct  30 2021 12:00AM','Order By Name Asc',''
ALTER PROCEDURE [dbo].[PA_Report_IndexPagingData]
    --10,1,'Order By Name Asc','',3
    -- Add the parameters for the stored procedure here
    @PageSize int,
    @PageIndex int,
    @startdt1 nvarchar(50),  
    @startdt2 nvarchar(50),
    @Sort nvarchar(50),
    @Search nvarchar(max)
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @qry nvarchar(max)
    DECLARE @TotalRecords nvarchar(max)

    SET @TotalRecords=' ( select count(*) from PA_Ledger pl join PA_Trans pt on (pl.LedgerId = pt.Ledgeridcr or pl.LedgerId = pt.Ledgeriddr ) 
                         where isnull(Isdeleted,0) = 0 and pl.Name like ''%'+@Search+'%'' 
                          and (pt.TransOn >= '''+convert(nvarchar,CONVERT(DATETIME,@startdt1,110))+''' or convert(date,'''+convert(nvarchar,CONVERT(DATETIME,@startdt1,110))+''') = convert(date,''01/01/1900'') )
                         and (pt.TransOn <='''+convert(nvarchar,CONVERT(DATETIME,@startdt2,110))+''' or convert(date,'''+convert(nvarchar,CONVERT(DATETIME,@startdt2,110))+''') = convert(date,''01/01/1900'') )
                         group by pl.Name)'
    

    
    set @qry = ' select  *, '+@TotalRecords+' As TotalRecords,                  
                        (select row_number() over(order by pl.name) as RowNo,pl.Name,sum(pt.Amount) as Amount
                         from PA_Ledger pl
                         join PA_Trans pt on (pl.LedgerId = pt.Ledgeridcr or pl.LedgerId = pt.Ledgeriddr)
                         and pl.Name like ''%'+@Search+'%'' and
                         isnull(Isdeleted,0) = 0 
                         and (pt.TransOn >= '''+convert(nvarchar,CONVERT(DATETIME,@startdt1,110))+''' or convert(date,'''+convert(nvarchar,CONVERT(DATETIME,@startdt1,110))+''') = convert(date,''01/01/1900'') )
                         and (pt.TransOn <='''+convert(nvarchar,CONVERT(DATETIME,@startdt2,110))+''' or convert(date,'''+convert(nvarchar,CONVERT(DATETIME,@startdt2,110))+''') = convert(date,''01/01/1900'') )
                         group by Name 
                        ) i where RowNo between  '+Convert(nvarchar(10),( (@pageIndex-1) * @pageSize  ) + 1 )+ ' and '  + Convert(varchar(10),( (@pageIndex-1) * @pageSize  ) + @pageSize) + ' '+ @Sort

    
    print(@qry)             
    exec(@qry+@TotalRecords)
    
END

当我执行时会产生如下错误:

( select count(*) from PA_Ledger pl join PA_Trans pt on (pl.LedgerId = pt.Ledgeridcr or pl.LedgerId = pt.Ledgeriddr ) 
                         where isnull(Isdeleted,0) = 0 and pl.Name like '%%' 
                          and (pt.TransOn >= 'Oct 28 2021 12:00AM' or convert(date,'Oct 28 2021 12:00AM') = convert(date,'01/01/1900') )
                         and (pt.TransOn <='Oct 30 2021 12:00AM' or convert(date,'Oct 30 2021 12:00AM') = convert(date,'01/01/1900') )
                         group by pl.Name)
 select  *,  ( select count(*) from PA_Ledger pl join PA_Trans pt on (pl.LedgerId = pt.Ledgeridcr or pl.LedgerId = pt.Ledgeriddr ) 
                         where isnull(Isdeleted,0) = 0 and pl.Name like '%%' 
                          and (pt.TransOn >= 'Oct 28 2021 12:00AM' or convert(date,'Oct 28 2021 12:00AM') = convert(date,'01/01/1900') )
                         and (pt.TransOn <='Oct 30 2021 12:00AM' or convert(date,'Oct 30 2021 12:00AM') = convert(date,'01/01/1900') )
                         group by pl.Name) As TotalRecords,
                        
                        (select row_number() over(order by pl.name) as RowNo,pl.Name,sum(pt.Amount) as Amount
                         from PA_Ledger pl
                         join PA_Trans pt on (pl.LedgerId = pt.Ledgeridcr or pl.LedgerId = pt.Ledgeriddr)
                         and pl.Name like '%%' and
                         isnull(Isdeleted,0) = 0 
                         and (pt.TransOn >= 'Oct 28 2021 12:00AM' or convert(date,'Oct 28 2021 12:00AM') = convert(date,'01/01/1900') )
                         and (pt.TransOn <='Oct 30 2021 12:00AM' or convert(date,'Oct 30 2021 12:00AM') = convert(date,'01/01/1900') )
                         group by Name 
                        ) i where RowNo between  1 and 100 Order By Name Asc

消息 207,第 16 层,状态 1,第 27 行
列名“RowNo”无效。

消息 207,第 16 层,状态 1,第 27 行
列名“RowNo”无效。

消息 263,第 16 级,状态 1,第 13 行
必须指定要从中选择的表。

消息 116,第 16 级,状态 1,第 27 行
当子查询不使用 EXISTS 引入时,选择列表中只能指定一个表达式。

消息 207,第 16 层,状态 1,第 27 行
列名“名称”无效。

此存储过程的更好解决方案是什么?请帮助我摆脱这种情况。

【问题讨论】:

  • 子查询在 FROM 之后使用。您在 SELECT 和 FROM 之间使用它们 - 您不能这样做。当该位置有括号时,sql server 期望单个值,而不是(派生)表。移动您的子查询。
  • @GeorgeMenoutis 请帮我处理你的代码。
  • 这段代码很危险,你应该通过sp_executesql正确参数化

标签: sql-server tsql


【解决方案1】:

好吧,你还没有给我们创建/插入查询,所以我们必须盲目。尝试更改set @qry 的第一行:

set @qry = ' select  *, '+@TotalRecords+' As TotalRecords,  

到这里:

set @qry = ' select  *, '+@TotalRecords+' As TotalRecords, i.* from 

这将导致您的括号 (...) i 成为派生表而不是单个值,并且我们选择它的所有元素 , i.*

另外,将@totalrecords 更改为具有备用别名的此版本:

set @TotalRecords=' ( select count(*) from PA_Ledger pl2 join PA_Trans pt2 on (pl2.LedgerId = pt2.Ledgeridcr or pl2.LedgerId = pt2.Ledgeriddr ) 
                         where isnull(Isdeleted,0) = 0 and pl2.Name like ''%'+@Search+'%'' 
                          and (pt2.TransOn >= '''+convert(nvarchar,CONVERT(DATETIME,@startdt1,110))+''' or convert(date,'''+convert(nvarchar,CONVERT(DATETIME,@startdt1,110))+''') = convert(date,''01/01/1900'') )
                         and (pt2.TransOn <='''+convert(nvarchar,CONVERT(DATETIME,@startdt2,110))+''' or convert(date,'''+convert(nvarchar,CONVERT(DATETIME,@startdt2,110))+''') = convert(date,''01/01/1900'') )
                         group by pl2.Name)'

【讨论】:

  • 已更改,但发生错误,例如 select , ( select count() from PA_Ledger pl join PA_Trans pt on (pl.LedgerId = pt.Ledgeridcr 或 pl.LedgerId = pt.Ledgeriddr ) ....... Msg 209, Level 16, State 1, Line 26 Ambiguous column name 'Name'。完成时间:2021-11-01T14:41:09.5418717+05:30
  • 啊,好吧,那是因为您在@TotalRecords@qry 上都使用了相同的别名(例如pl)。更改其中之一的别名,例如 pl->pl2、pt->pt2 等
  • 请更新您的代码。这对我有很大帮助
  • 添加了 @TotalRecords 更改
猜你喜欢
  • 2021-06-17
  • 1970-01-01
  • 1970-01-01
  • 2019-06-13
  • 2020-01-02
  • 2021-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多