在动态查询中获取输出

问题描述 投票:-1回答:2

我正在创建一个要获取输出参数值的存储过程。这就是打击查询中的@RecordCount INT OUTPUT。但是我无法从SP下方获取OUTPUT参数的值。

ALTER PROCEDURE [dbo].[GetOrderListByClient]                
 @PageIndex INT = 1                
  ,@PageSize INT = 10                
  ,@orderNumber varchar(15) = null,           
  @ref varchar(255) = null,                
  @OrderstartDate date = null ,                
  @OrderEndDate date= null ,                
  @ClientId varchar(1000) ,                
  @RecordCount INT OUTPUT                
AS        
BEGIN 
   IF  @OrderEndDate IS NULL Or @OrderEndDate = ''      
         SET @OrderEndDate =CONVERT(Varchar(14), GETDATE(),101)   


  SET @OrderstartDate = CONVERT(varchar(10),@OrderstartDate,101)                
  SET @OrderEndDate =CONVERT(VARCHAR(10),@OrderEndDate,101)                
  SET NOCOUNT ON;

    DECLARE @QUERY VARCHAR(MAX)  
    DECLARE @FINALQUERY VARCHAR(MAX)    
    DECLARE @QUERY2 VARCHAR(MAX)




    SET @QUERY =

 ' 


  DECLARE @temp table                
    (                 
     RowNumber int ,                
     ORDERID int,                
     ORDERNUM varchar(15) NULL,                
     READYDATE date NULL,                
     ref varchar(255) NULL,                
     PADDR varchar(40) NULL,                
     DADDR varchar(40) NULL,                
     DCity varchar(25) NULL,                
     readyTime datetime2(7) NULL,                
     PICKTIME time null,                
     DRV1ID int null,                
     TOTAL decimal(10,2) NULL,                
     DeliveryTime time null,          
     PCITY varchar(40) null,          
     PICKUP varchar(40) null,          
     DROPOFF varchar(40) null,    
     PICTURECOUNT int                  
     )  



 INSERT INTO @temp                
    SELECT ROW_NUMBER() OVER                
  (                
        ORDER BY [ORDERNUM] DESC                
  )AS RowNumber                
  ,O.ORDERID, O.ORDERNUM, CONVERT(VARCHAR(11),CAST(O.READYDATE as DATE) ) AS READYDATE,O.Ref,O.PADDR,O.DADDR,          
  O.DCity,CONVERT(VARCHAR(5),O.readyTime,14)AS readyTime,CONVERT (VARCHAR(5),CAST(O.PICKTIME as Time)) AS PICKTIME,          
  O.DRV1ID,O.TOTAL,CONVERT (VARCHAR(5),CAST(O.DELIVERBY as Time)) AS DeliveryTime,PCITY,PICKUP,DROPOFF,O.PICTURECOUNT                           
  --INTO @temp                
  from Orde_  O                 
  WHERE  '

  IF (@QUERY <>'')
       SET @QUERY = @QUERY + ' CANCELLED = 0 ' 
   ELSE
       SET @QUERY = @QUERY + ' AND CANCELLED = 0 '

  IF (@QUERY2 ='')
       SET @QUERY = @QUERY +  ' CLIENTID IN (' +  @ClientId +')'
   ELSE
       SET @QUERY = @QUERY +  ' AND CLIENTID IN (' +  @ClientId +')'


  --if( @orderNumber <>'')
  --    SET @QUERY2 = @QUERY + ' AND ORDERNUM = '''+ @orderNumber+''

  IF (@ref <> '')
    BEGIN
      IF @QUERY2 = ''
           SET @QUERY = @QUERY + ' REF Like %'''+ @ref + '%'''
      ELSE
           SET @QUERY = @QUERY + ' AND  REF Like %'''+ @ref+ '%'''
    END 



  --  AND ((READYDATE  BETWEEN '''+ CONVERT(VARCHAR(10), @OrderstartDate,101)+''' AND  '''+  CONVERT(VARCHAR(10),@OrderEndDate,101)+''')  OR ( '+  CONVERT(VARCHAR(10), @OrderstartDate,101)+' IS NULL OR READYDATE >= '''+ CONVERT(VARCHAR(10),@OrderstartDate,101)+''' )       
  --  AND ('''+ CONVERT(VARCHAR(10), @OrderEndDate,101)+''' IS NULL OR READYDATE <= '''+CONVERT(VARCHAR(10),@OrderEndDate,101)+'''))) '     

    SET @QUERY  = @QUERY + '         

     SELECT  @RecordCount= COUNT(1)  FROM @temp                 

    SELECT * FROM @temp                
     WHERE RowNumber BETWEEN ( '+ CONVERT(VARCHAR(20), @PageIndex) +' -1) * '+ CONVERT(VARCHAR(20),@PageSize) +' + 1 AND((( '+ CONVERT(VARCHAR(10),@PageIndex)+' -1) * '+ CONVERT(VARCHAR(10),@PageSize)+' + 1) + '+ CONVERT(VARCHAR(10),@PageSize)+') - 1 '               


   PRINT  @QUERY
   --exec   (@QUERY)  

  -- Execute sp_Executesql @Query , @PageIndex,@PageSize,@OrderstartDate,@OrderEndDate,@ClientId, @RecordCount OUTPUT        
 -- DROP TABLE #Results                
END 
sql sql-server tsql sql-server-2008-r2
2个回答
0
投票

这是一个示例查询,但是,它应该使您走上正确的道路。您所拥有的是一个巨大的安全问题,需要修复。您的查询中没有任何动态对象,由于查询是“全部查询”,因此仅使用动态SQL。此方法对于此类查询(我个人推荐)很好,但您必须参数化您的查询(再次为Dos and Don'ts of Dynamic SQL)。

之前,该查询至少向您展示了如何使用OUTPUT参数创建动态查询:

CREATE TABLE dbo.YourTable (ID int IDENTITY,
                            SomeString varchar(25),
                            SomeInt int)
GO                          
CREATE PROC dbo.YourProc @SomeString varchar(25) = NULL, @SomeInt int = NULL, @RowCount int OUTPUT AS
BEGIN

    DECLARE @SQL nvarchar(MAX),
            @CRLF nchar(2) = NCHAR(13) + NCHAR(10);


    SET @SQL = N'SELECT @RowCount = COUNT(*)' + @CRLF +
               N'FROM dbo.YourTable' + @CRLF +
               CASE WHEN @SomeString IS NOT NULL OR @SomeInt IS NOT NULL
                         THEN N'WHERE ' + STUFF(CASE WHEN @SomeString IS NOT NULL THEN @CRLF + N'  AND SomeString = @SomeString' ELSE N'' END +
                                                CASE WHEN @SomeInt IS NOT NULL THEN @CRLF + N'  AND SomeInt = @SomeInt' ELSE N''END,1,8,N'')
                         ELSE ''
               END + N';';

    EXEC sp_executesql @SQL, N'@SomeString varchar(25), @SomeInt int, @RowCount int OUTPUT', @SomeString, @SomeInt, @RowCount OUTPUT;

END;
GO

DECLARE @RowCount int;
EXEC dbo.YourProc @SomeString = NULL,
                  @SomeInt = NULL,
                  @RowCount = @RowCount OUTPUT;

SELECT @RowCount; --0
GO

INSERT INTO dbo.YourTable (SomeString,
                           SomeInt)
VALUES('sdfgsdfg',1),
      ('sdfjhsdgfs',1),
      ('sdfgkhjdfbgk',2);
GO

DECLARE @RowCount int;
EXEC dbo.YourProc @SomeString = NULL,
                  @SomeInt = 1,
                  @RowCount = @RowCount OUTPUT;
SELECT @RowCount; --2
GO

DECLARE @RowCount int;
EXEC dbo.YourProc @SomeString = 'sdfjhsdgfs',
                  @SomeInt = 1,
                  @RowCount = @RowCount OUTPUT;
SELECT @RowCount; --1

GO

DROP PROC dbo.YourProc;
DROP TABLE dbo.YourTable;

-1
投票

请尝试以下查询,让我知道问题是否已解决。

ALTER PROCEDURE [dbo].[GetOrderListByClient] @PageIndex INT = 1
    ,@PageSize INT = 10
    ,@orderNumber VARCHAR(15) = NULL
    ,@ref VARCHAR(255) = NULL
    ,@OrderstartDate DATE = NULL
    ,@OrderEndDate DATE = NULL
    ,@ClientId VARCHAR(1000)
    ,@RecordCount INT OUTPUT
AS
BEGIN
    IF @OrderEndDate IS NULL
        OR @OrderEndDate = ''
        SET @OrderEndDate = CONVERT(VARCHAR(14), GETDATE(), 101)
    SET @OrderstartDate = CONVERT(VARCHAR(10), @OrderstartDate, 101)
    SET @OrderEndDate = CONVERT(VARCHAR(10), @OrderEndDate, 101)
    SET NOCOUNT ON;

    DECLARE @QUERY VARCHAR(MAX)
    DECLARE @FINALQUERY VARCHAR(MAX)
    DECLARE @QUERY2 VARCHAR(MAX)

    SET @QUERY = 
        ' 
DECLARE @temp table                
    (                 
     RowNumber int ,                
     ORDERID int,                
     ORDERNUM varchar(15) NULL,                
     READYDATE date NULL,                
     ref varchar(255) NULL,                
     PADDR varchar(40) NULL,                
     DADDR varchar(40) NULL,                
     DCity varchar(25) NULL,                
     readyTime datetime2(7) NULL,                
     PICKTIME time null,                
     DRV1ID int null,                
     TOTAL decimal(10,2) NULL,                
     DeliveryTime time null,          
     PCITY varchar(40) null,          
     PICKUP varchar(40) null,          
     DROPOFF varchar(40) null,    
     PICTURECOUNT int                  
     )  



 INSERT INTO @temp                
    SELECT ROW_NUMBER() OVER                
  (                
        ORDER BY [ORDERNUM] DESC                
  )AS RowNumber                
  ,O.ORDERID, O.ORDERNUM, CONVERT(VARCHAR(11),CAST(O.READYDATE as DATE) ) AS READYDATE,O.Ref,O.PADDR,O.DADDR,          
  O.DCity,CONVERT(VARCHAR(5),O.readyTime,14)AS readyTime,CONVERT (VARCHAR(5),CAST(O.PICKTIME as Time)) AS PICKTIME,          
  O.DRV1ID,O.TOTAL,CONVERT (VARCHAR(5),CAST(O.DELIVERBY as Time)) AS DeliveryTime,PCITY,PICKUP,DROPOFF,O.PICTURECOUNT                           
  --INTO @temp                
  from Orde_  O                 
  WHERE  '

    IF (@QUERY <> '')
        SET @QUERY = @QUERY + ' CANCELLED = 0 '
    ELSE
        SET @QUERY = @QUERY + ' AND CANCELLED = 0 '

    IF (@QUERY2 = '')
        SET @QUERY = @QUERY + ' CLIENTID IN (' + @ClientId + ')'
    ELSE
        SET @QUERY = @QUERY + ' AND CLIENTID IN (' + @ClientId + ')'

    --if( @orderNumber <>'')
    --    SET @QUERY2 = @QUERY + ' AND ORDERNUM = '''+ @orderNumber+''
    IF (@ref <> '')
    BEGIN
        IF @QUERY2 = ''
            SET @QUERY = @QUERY + ' REF Like %''' + @ref + '%'''
        ELSE
            SET @QUERY = @QUERY + ' AND  REF Like %''' + @ref + '%'''
    END

    --  AND ((READYDATE  BETWEEN '''+ CONVERT(VARCHAR(10), @OrderstartDate,101)+''' AND  '''+  CONVERT(VARCHAR(10),@OrderEndDate,101)+''')  OR ( '+  CONVERT(VARCHAR(10), @OrderstartDate,101)+' IS NULL OR READYDATE >= '''+ CONVERT(VARCHAR(10),@OrderstartDate,101)+''' )       
    --  AND ('''+ CONVERT(VARCHAR(10), @OrderEndDate,101)+''' IS NULL OR READYDATE <= '''+CONVERT(VARCHAR(10),@OrderEndDate,101)+'''))) '     
    SET @QUERY = @QUERY + '         

     SELECT  @RecordCount= COUNT(1)  FROM @temp ' + '             

    SELECT * FROM @temp                
     WHERE RowNumber BETWEEN (' + '+ CONVERT(VARCHAR(20), @PageIndex) ' + ' -1) * ' + ' CONVERT(VARCHAR(20),@PageSize)' + ' 1 AND((( ' + 'CONVERT(VARCHAR(10),@PageIndex)' + ' -1) * ' + ' CONVERT(VARCHAR(10),@PageSize)' + ' 1) ' + '+ CONVERT(VARCHAR(10),@PageSize)' + ') - 1 '

    --PRINT @QUERY
        exec   (@QUERY)  
         Execute sp_Executesql @Query , @PageIndex,@PageSize,@OrderstartDate,@OrderEndDate,@ClientId, @RecordCount OUTPUT        
        -- DROP TABLE #Results                
END
© www.soinside.com 2019 - 2024. All rights reserved.