Сохранить результаты существующего запроса в переменную - PullRequest
3 голосов
/ 10 апреля 2019

Я хочу сохранить результат этого EXISTS запроса в переменную:

DECLARE @max_date DATETIME2
DECLARE @DatabaseSchema VARCHAR(MAX)

SET @DatabaseSchema = 'SALES_MART'
SET @max_date = CASE 
                   WHEN EXISTS(SELECT MAX(SaleDate)
                               FROM  @DatabaseSchema.SalesReport
                               WHERE Categoryname = 'Asia')
                      THEN (SELECT MAX(SaleDate)
                            FROM  @DatabaseSchema.SalesReport
                            WHERE Categoryname = 'Asia')
                      ELSE GETDATE()
                END

EXEC @max_date

Когда я его выполняю, я получаю ошибку

неверное имя столбца @DatabaseName.SalesReport

Причиной ошибки является то, что SQL Server не принимает переменную после FROM.

Я гуглил и пытался удалить «CASE WHEN», но это все еще нене работаетМожете ли вы помочь мне с этим запросом?Как мне отредактировать его?

Это моя тестовая таблица:

CREATE SCHEMA SALES_MART;

CREATE TABLE SALES_MART.SalesReport  
( 
     id INT,
     SaleDate DATETIME2,
     sales INT,
     Categoryname VARCHAR(100)
);

INSERT INTO SALES_MART.SalesReport  
VALUES (1, '1905-07-08 00:00:00.000', 50, 'Asia'),
       (2, '1905-07-08 00:00:00.000', 90, 'Asia'),
       (3, '1905-07-08 00:00:00.000', 100, 'EU');

Ответы [ 4 ]

1 голос
/ 10 апреля 2019

Предполагая, что вы используете SSMS в качестве IDE, вы можете просто включить Sql Command Mode , и тогда вы сможете получить динамическое значение схемы. Попробуйте следующий код:

:SetVar DatabaseSchema "SALES_MART"

CREATE SCHEMA $(DatabaseSchema);
GO

CREATE TABLE $(DatabaseSchema).SalesReport  
( 
     id INT,
     SaleDate DATETIME2,
     sales INT,
     Categoryname VARCHAR(100)
);
GO

INSERT INTO $(DatabaseSchema).SalesReport  
VALUES (1, '1905-07-08 00:00:00.000', 50, 'Asia'),
       (2, '1905-07-08 00:00:00.000', 90, 'Asia'),
       (3, '1905-07-08 00:00:00.000', 100, 'EU');

DECLARE @max_date DATETIME2

SET @max_date = CASE 
                   WHEN EXISTS(SELECT MAX(SaleDate)
                               FROM  $(DatabaseSchema).SalesReport
                               WHERE Categoryname = 'Asia')
                      THEN (SELECT MAX(SaleDate)
                            FROM  $(DatabaseSchema).SalesReport
                            WHERE Categoryname = 'Asia')
                      ELSE GETDATE()
                END

PRINT @max_date

-- Clean up
DROP TABLE $(DatabaseSchema).SalesReport;
GO

DROP SCHEMA $(DatabaseSchema);
GO
0 голосов
/ 10 апреля 2019

Если вы хотите использовать параметр для имени вашей схемы, вам нужно будет использовать динамический SQL.Он преобразует вашу строку в запрос, так что вы можете объединить ваш строковый параметр со строкой запроса, который вы написали.Вы также можете вывести значение в параметр.

Я упростил ваш запрос, используя coalesce.Принимает первое значение, если не NULL, и второе, если первое - NULL

Declare @DatabaseSchema varchar(max)
SET @DatabaseSchema ='SALES_MART'
DECLARE @MaxDate DATETIME
DECLARE @Query NVARCHAR(MAX) = 'SELECT COALESCE((SELECT max(SaleDate) FROM '+ @DatabaseSchema + '.SalesReport WHERE Categoryname = ''Asia''), GETDATE())' 
EXECUTE sp_executesql @Query, N'@Output DATETIME OUT', @MaxDate OUT
PRINT @MaxDate
0 голосов
/ 10 апреля 2019
Переменные

недопустимы в именах серверов, схем и таблиц, а также в нескольких других местах (например, в ALTER, CREATE, DROP ..etc).

В вашем случае вы пытаетесь использовать его в имени схемы, чтобы использовать его следующим образом, у вас будет два варианта.

Опция 1:

Определите каждый оператор выбора и используйте IF, чтобы получить нужный оператор выбора на основе ввода переменной.

Пример:

DECLARE
    @max_date       DATETIME2
,   @DatabaseSchema VARCHAR(max) = 'SALES_MART'

SET @max_date = CASE @DatabaseSchema
                    WHEN 'SALES_MART'       THEN (SELECT MAX(SaleDate) FROM SALES_MART.SalesReport WHERE Categoryname = 'Asia')
                    WHEN 'SALES_MART_TWO'   THEN (SELECT MAX(SaleDate) FROM SALES_MART_TWO.SalesReport WHERE Categoryname = 'Asia')
                    ELSE GETDATE()
                END 

SET @max_date = CASE WHEN @max_date IS NULL THEN GETDATE() ELSE @max_date END -- You can replace it with ISNULL(@max_date, GETDATE()) 

SELECT @max_date

Вариант 2 (Не всегда рекомендуется, так как имеет свои собственные риски):

Вместо этого используйте daynamic sql.

DECLARE
    @max_date       DATETIME2
,   @DatabaseSchema VARCHAR(max) = 'SALES_MART'
,   @sql            VARCHAR(max) = ''

    SET @sql = 'ISNULL( (SELECT MAX(SaleDate) FROM @DatabaseSchema.SalesReport WHERE Categoryname = ''Asia''), GETDATE())'

    SET @sql = REPLACE(@sql, '@DatabaseSchema',  @DatabaseSchema)

    EXEC (@sql)
0 голосов
/ 10 апреля 2019

Вот исправленный код, который сохраняет результат в переменной @max_date. Последний выбор предназначен для отображения результата

    CREATE SCHEMA SALES_MART;
    go
    create table SALES_MART.SaleReport  (id int,SaleDate datetime2,sales int,Categoryname varchar(100));
    INSERT INTO SALES_MART.SaleReport  
    VALUES
    (1,'1905-07-08 00:00:00.000',50,'Asia'),
    (2,'1905-07-08 00:00:00.000',90,'Asia'),
    (3,'1905-07-08 00:00:00.000',100,'EU');


     Declare @max_date  datetime2
     Declare @DatabaseSchema varchar(max)


        SElect   @max_date=CASE WHEN EXISTS(SELECT max(SaleDate)
                                            FROM  SALES_MART.SaleReport 
                                            WHERE Categoryname = 'Asia')
                             THEN (SELECT max(SaleDate)
                                            FROM  SALES_MART.SaleReport 
                                            WHERE Categoryname = 'Asia' )
                            ELSE getdate()  END

    select @max_date [result in varaiable]


[![enter image description here][1]][1]


  [1]: https://i.stack.imgur.com/ImC1o.png







**ANOTHER SOLUTION WITH DYNAMIC SCRIPT**
This solution can be used for many schemas, it inserts the result (with the schema name and max date) in Tbale mytable


CREATE SCHEMA SALES_MART;
go
create table SALES_MART.SaleReport  (id int,SaleDate datetime2,sales int,Categoryname varchar(100));
INSERT INTO SALES_MART.SaleReport  
VALUES
(1,'1905-07-08 00:00:00.000',50,'Asia'),
(2,'1905-07-08 00:00:00.000',90,'Asia'),
(3,'1905-07-08 00:00:00.000',100,'EU');


 Declare @max_date  datetime2
 Declare @DatabaseSchema varchar(max)
 set @DatabaseSchema='SALES_MART'
 declare @script as varchar(max)

 create table mytable(myschema varchar(50),maxdate date)
 delete from mytable
 set @script='
    insert into mytable (myschema,maxdate)
    select '''+@DatabaseSchema+''',
    CASE WHEN EXISTS(SELECT max(SaleDate)
                                        FROM  '+@DatabaseSchema+'.SaleReport 
                                        WHERE Categoryname = ''Asia'')
                         THEN (SELECT max(SaleDate)
                                        FROM  SALES_MART.SaleReport 
                                        WHERE Categoryname = ''Asia'' )
                        ELSE getdate()  END'

exec(@script)

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