Как исправить этот запрос в SQL Server 2005 - PullRequest
0 голосов
/ 07 октября 2009

У меня есть запрос, который объединяет два запроса, в результате запрос возвращает повторяющиеся записи, я не хочу повторяющихся записей. Я пытался использовать DISTINCT, но все равно получал тот же результат, кто-нибудь может мне помочь исправить этот запрос?

Я также хочу знать, безопасен ли этот запрос от SQL-инъекции ... Я вставлю свой запрос ниже:

ALTER PROCEDURE [dbo].[sp_GetTrashListWithSorting] --'6dbf9a01-c88f-414d-8dd9-696749258cef', '6dbf9a01-c88f-414d-8dd9-696749258cef','DateTime ASC','0','30'
(
    @p_CreatedBy UNIQUEIDENTIFIER,
    @p_ToReceipientID UNIQUEIDENTIFIER,
    @p_SortExpression NVARCHAR(100),
    @p_StartIndex INT,
    @p_MaxRows INT
)
AS
    SET NOCOUNT ON;

    IF LEN(@p_SortExpression) = 0 
       SET @p_SortExpression ='DateTime DESC'

    DECLARE @Sql NVARCHAR(4000)

    SET @sql = 'SELECT ID, DateTime, Subject, CreatedBy, ToReceipientID, Status
                FROM (SELECT ID, 
                             DateTime, 
                             Subject, 
                             CreatedBy, 
                             ToReceipientID, 
                             Status,
                             ROW_NUMBER() OVER(ORDER BY '+ @p_SortExpression +') AS Indexing
                      FROM (SELECT ID,
                                   DateTime, 
                                   Subject, 
                                   CreatedBy, 
                                   ToReceipientID, 
                                   SenderStatus AS Status
                             FROM ComposeMail 
                             WHERE (CreatedBy = @p)
                               AND (SenderStatus = 7 OR SenderStatus = 8)
                             UNION
                             SELECT ID,
                                    DateTime, 
                                    Subject, 
                                    CreatedBy, 
                                    ToReceipientID, 
                                    ReceiverStatus As Status
                              FROM ComposeMail
                              WHERE (ToReceipientID = @p1) 
                                AND (ReceiverStatus = 7 OR ReceiverStatus = 8)) AS NewDataTable
            ) AS IndexTable
   WHERE 
       Indexing > @p2 AND Indexing<= (@p2+@p3)' 

   DECLARE @paramDefinition NVARCHAR(500)

   SET @paramDefinition = N'@p UNIQUEIDENTIFIER ,@p1 UNIQUEIDENTIFIER, @p2 INT, @p3 INT'

   EXEC sp_executesql @sql, @paramDefinition,
                @p = @p_CreatedBy,
                @p1 = @p_ToReceipientID,
                @p2 = @p_StartIndex ,
                @p3 = @p_MaxRows

Ответы [ 2 ]

3 голосов
/ 07 октября 2009

1) Я переписал ваш SQL как:

WITH trash_list AS (
SELECT cm.id,
       cm.datetime, 
       cm.subject,
       cm.createdby,
       cm.toreceipientid, 
       cm.senderstatus AS Status
  FROM COMPOSEMAIL cm
 WHERE cm.createdBy = @p
   AND cm.enderStatus IN(7, 8)
UNION
SELECT cm.id,
       cm.datetime, 
       cm.subject,
       cm.createdby,
       cm.toreceipientid, 
       cm.receiverstatus AS Status
  FROM COMPOSEMAIL cm
 WHERE cm.toreceipientid = @p1
   AND cm.receiverstatus IN (7, 8))
SELECT t.id,
       t.datetime, 
       t.subject,
       t.createdby,
       t.toreceipientid, 
       t.status
  FROM (SELECT tl.id,
               tl.datetime, 
               tl.subject,
               tl.createdby,
               tl.toreceipientid, 
               tl.status,
               ROW_NUMBER() OVER(ORDER BY '+ @p_SortExpression +') AS Indexing
          FROM trash_list tl
      GROUP BY tl.id,
               tl.datetime, 
               tl.subject,
               tl.createdby,
               tl.toreceipientid, 
               tl.status) t
 WHERE t.indexing BETWEEN @p2 AND (@p2+@p3)

... но если вы все еще получаете дубликаты, проверьте логику в SELECT / UNION в предложении WITH.

Перед тем как превратить его в динамический SQL, заставьте его работать как обычный SQL.

2) Запрос не защищен от атак с использованием инъекций, поскольку вы не обрабатываете одинарные кавычки, когда пользователи могут предоставить текст:

IF LEN(@p_SortExpression)=0 
  SET @p_SortExpression ='DateTime DESC'

... должно быть:

IF LEN(@p_SortExpression)=0 
  SET @p_SortExpression ='DateTime DESC'
ELSE
  SET @p_SortExpression = REPLACE(@p_SortExpression, '''', '''''')
0 голосов
/ 27 сентября 2015

Вам не нужны запросы и объединение. Вместо этих 2 строк (по одной на каждый подзапрос)

                         WHERE (CreatedBy = @p)
                         WHERE (ToReceipientID = @p1) 

сделать это (в одном запросе)

                         WHERE CreatedBy IN (@p, @p1)

Как это:

SELECT
      ID
    , DateTime
    , Subject
    , CreatedBy
    , ToReceipientID
    , Status
FROM (
      SELECT
            ID
          , DateTime
          , Subject
          , CreatedBy
          , ToReceipientID
          , SenderStatus AS Status
          , ROW_NUMBER() OVER (ORDER BY ' + @p_SortExpression + ') AS Indexing
      FROM ComposeMail
      WHERE CreatedBy IN (@p, @p1)
            AND (SenderStatus = 7
            OR SenderStatus = 8)
) AS IndexTable
WHERE Indexing > @p2
      AND Indexing <= (@p2 + @p3)

ОДНАКО Я не уверен, что понимаю, как вы передаете значения для @p или @ p1

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...