Просмотр, хранимая процедура или определенная в таблице функция - PullRequest
3 голосов
/ 26 января 2011

Этот запрос выполняется просто как есть. Однако SQL Management Studio не сохранит его как представление, поскольку я определяю переменную.

DECLARE @HighestTransaction int

SET @HighestTransaction = (SELECT     MAX(CardID)
                            FROM          dbo.Transactions)

SELECT Uploads.*, Transactions.*
FROM   Uploads LEFT OUTER JOIN
       dbo.Transactions ON dbo.Uploads.Code = dbo.Transactions.CardID
WHERE  (Uploads.Code > CASE WHEN
           @HighestTransaction IS NULL THEN -1  ELSE @HighestTransaction END)

На самом деле я не слишком много играл с хранимыми процедурами или пользовательскими функциями, поэтому не уверен, что это лучший способ сделать это. Или, если есть лучший способ написать это, я также открыт для предложений.

Ответы [ 7 ]

5 голосов
/ 26 января 2011
  • Вы можете выделить MAX в CTE
  • MAX без GROUP BY дает одну строку, так что вы используете ISNULL там

Что-то вроде ...

WITh cHighestCard AS
(
   SELECT ISNULL(MAX(CardID), -1) AS MaxCard FROM dbo.Transactions
)
SELECT     STAUpload.*, Transactions.*
FROM         dbo.STAUpload LEFT OUTER JOIN
                      dbo.Transactions ON dbo.STAUpload.Code = dbo.Transactions.CardID
WHERE     dbo.STAUpload.Code > MaxCard --edit, error spotted by martin

Редактировать: CTE не требуется: он смешивает множества и скаляры.Упс.

SELECT     STAUpload.*, Transactions.*
FROM         dbo.STAUpload LEFT OUTER JOIN
                      dbo.Transactions ON dbo.STAUpload.Code = dbo.Transactions.CardID
WHERE     dbo.STAUpload.Code >
            (SELECT ISNULL(MAX(CardID), -1) AS MaxCard
                   FROM dbo.Transactions)
2 голосов
/ 26 января 2011

Поскольку вы упомянули, что пытались создать это как представление, это означает, что вы можете захотеть использовать результаты в другом запросе. Если это так, я бы сделал эту табличную функцию .

0 голосов
/ 27 января 2011

Просто CROSS ПРИСОЕДИНЯЙТЕСЬ к подзапросу, который инициализирует @HighestTansaction к вашему основному запросу, например:

SELECT Uploads.*, Transactions.*
FROM   Uploads LEFT OUTER JOIN
       dbo.Transactions ON dbo.Uploads.Code = dbo.Transactions.CardID CROSS JOIN
       (SELECT ISNULL(MAX(CardID),-1) FROM dbo.Transactions) m(HighestTransaction)
WHERE  (Uploads.Code > m.HighestTransaction)
0 голосов
/ 27 января 2011

Это может быть только одно простое представление, работающее без использования CTE. ISNULL против SELECT MAX в подзапросе может быть проще интерпретировать это включение ISNULL в подзапрос.

CREATE VIEW Q_SO
AS
SELECT Uploads.*, Transactions.*
FROM Uploads
LEFT OUTER JOIN dbo.Transactions
    ON dbo.Uploads.Code = dbo.Transactions.CardID
WHERE (Uploads.Code > ISNULL((SELECT MAX(CardID) FROM dbo.Transactions),-1))

в качестве функции без параметров.

CREATE FUNCTION Q_FN() RETURNS TABLE AS RETURN
SELECT Uploads.*, Transactions.*
FROM Uploads
LEFT OUTER JOIN dbo.Transactions
    ON dbo.Uploads.Code = dbo.Transactions.CardID
WHERE (Uploads.Code > ISNULL((SELECT MAX(CardID) FROM dbo.Transactions),-1))
0 голосов
/ 26 января 2011

Вы можете сделать это в хранимой процедуре. Просто передайте вашу переменную, и она будет работать как вам нужно.

Выполните быстрый поиск и просмотр хранимых процедур в MSDN или книгах в Интернете.

0 голосов
/ 26 января 2011

Вы можете перекодировать его как подзапрос с COALESCE, чтобы не вводить его дважды:

SELECT ....
  FROM ....
 WHERE dbo.STAUpload.code > COALESCE( 
       (Select max(cardId) from dbo.transactions),-1)

Тогда он становится представлением.

0 голосов
/ 26 января 2011

Это хранимая процедура. Это просто, как пирог в использовании. Просто скажите управляющей студии, что вы хотите создать новую процедуру, и она даже создаст для вас весь базовый синтаксис фреймворка.

http://msdn.microsoft.com/en-us/library/ms345415.aspx

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