Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Результат запроса (N строк) в скалярную переменную  [new]
mezzanine
Member

Откуда:
Сообщений: 157
Доброго дня.

Довольно неожиданно для меня было то что запрос который возвращает больше одной записи нормально работает со скалярной переменной. Просто по опыту в Оракле в таком случае сервер генерирует логичную ошибку: TOO_MANY_ROWS You tried to execute a SELECT INTO statement and more than one row was returned.
Такие ошибки искать просто жуть как трудно. Ожидаешь одну запись, потом что-то поменялась в данных и запрос ошибочно возвращает 2 записи.
Может в MS так тоже можно сделать? Не проверяя "ручками" результаты запроса и генерируя собственный эксепшен.

DECLARE @int INT;

WITH cte
AS (SELECT 1 id
UNION ALL
SELECT 2 id)
SELECT @int = id
  FROM cte

SELECT @int;
23 мар 16, 18:38    [18969876]     Ответить | Цитировать Сообщить модератору
 Re: Результат запроса (N строк) в скалярную переменную  [new]
o-o
Guest
SELECT @local_variable (Transact-SQL)
BOL
SELECT @local_variable is typically used to return a single value into the variable.
However, when expression is the name of a column, it can return multiple values.
If the SELECT statement returns more than one value, the variable is assigned the last value that is returned.

в явном виде сказано, что не будет ошибки,
и не вернет никакую кучу значений,
а вернет последнее обработанное.
не нравится такое поведение, не используйте переменную.
я такое использую, когда мне надо весь офигительный запрос прогнать,
получить план с реальными цифрами и временем,
но гнать результат на клиент мне не надо
и вставлять куда-то тоже не желаю
23 мар 16, 18:46    [18969925]     Ответить | Цитировать Сообщить модератору
 Re: Результат запроса (N строк) в скалярную переменную  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
Присваивать можно по разному...

DECLARE @int INT

SET @int = (
    SELECT id
    FROM (
        VALUES (1), (2)
    ) t(id)
)

SELECT @int

и выбирают люди так как им будет удобно.
23 мар 16, 18:47    [18969931]     Ответить | Цитировать Сообщить модератору
 Re: Результат запроса (N строк) в скалярную переменную  [new]
mezzanine
Member

Откуда:
Сообщений: 157
AlanDenton,

Огромное спасибо! То что доктор прописал.
23 мар 16, 18:49    [18969939]     Ответить | Цитировать Сообщить модератору
 Re: Результат запроса (N строк) в скалярную переменную  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
К слову будет сказано, начиная с 2008 сервера можно совмещать объявление переменной и ее инициализацию:

DECLARE @int INT = (
    SELECT id
    FROM (
        VALUES (1), (2)
    ) t(id)
)
23 мар 16, 18:51    [18969948]     Ответить | Цитировать Сообщить модератору
 Re: Результат запроса (N строк) в скалярную переменную  [new]
mezzanine
Member

Откуда:
Сообщений: 157
AlanDenton,

В такой способ можно присвоить значение больше чем одной переменной?
23 мар 16, 18:54    [18969961]     Ответить | Цитировать Сообщить модератору
 Re: Результат запроса (N строк) в скалярную переменную  [new]
iap
Member

Откуда: Москва
Сообщений: 47001
mezzanine
AlanDenton,

В такой способ можно присвоить значение больше чем одной переменной?
Всё так же, как и с SET
23 мар 16, 18:57    [18969976]     Ответить | Цитировать Сообщить модератору
 Re: Результат запроса (N строк) в скалярную переменную  [new]
mezzanine
Member

Откуда:
Сообщений: 157
iap,

Например, как одним запросом получить значение полей id1, id2 ?
DECLARE @int INT

SET @int = (SELECT t.id1
  FROM (VALUES (1, 11)) t (id1, id2))

SELECT @int
23 мар 16, 19:01    [18969993]     Ответить | Цитировать Сообщить модератору
 Re: Результат запроса (N строк) в скалярную переменную  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
Вот несколько вариантов для Вашего первоначального условия:

DECLARE
    @i1 INT,
    @i2 INT 

SELECT
    @i1 = id1,
    @i2 = id2
FROM (
    VALUES (1,1), (2,1)
) t(id1, id2)

IF @@rowcount > 1
    RAISERROR('err', 16, 1)

либо уповать на лишние логические чтения из одной и той же таблицы:

DECLARE
    @i1 INT,
    @i2 INT 

SET @i1 = (SELECT ...)
SET @i2 = (SELECT ...)
23 мар 16, 19:04    [18970005]     Ответить | Цитировать Сообщить модератору
 Re: Результат запроса (N строк) в скалярную переменную  [new]
o-o
Guest
mezzanine
iap,

Например, как одним запросом получить значение полей id1, id2 ?
DECLARE @int INT

SET @int = (SELECT t.id1
  FROM (VALUES (1, 11)) t (id1, id2))

SELECT @int

переменная это вам не автобус, где указано 54 сидячих места,
а по факту можно сотню человек штабелями уложить
23 мар 16, 19:04    [18970009]     Ответить | Цитировать Сообщить модератору
 Re: Результат запроса (N строк) в скалярную переменную  [new]
mezzanine
Member

Откуда:
Сообщений: 157
AlanDenton,

Еще раз спасибо. Буду использовать 2 опции. Ваш вариант с одной переменной, ну и где нужно больше одной переменной то генерировать исключение.
23 мар 16, 19:10    [18970029]     Ответить | Цитировать Сообщить модератору
 Re: Результат запроса (N строк) в скалярную переменную  [new]
mezzanine
Member

Откуда:
Сообщений: 157
o-o,

В Оракле более прозрачно в таких вещах:
1. SELECT INTO только скалярные переменные, больше 1 строки ошибка.
2. SELECT INTO BULK COLLECT только табличные переменные, 0-N строк без ошибок
23 мар 16, 19:13    [18970046]     Ответить | Цитировать Сообщить модератору
 Re: Результат запроса (N строк) в скалярную переменную  [new]
invm
Member

Откуда: Москва
Сообщений: 9406
AlanDenton
либо уповать на лишние логические чтения из одной и той же таблицы:

DECLARE
    @i1 INT,
    @i2 INT 

SET @i1 = (SELECT ...)
SET @i2 = (SELECT ...)
Лишние чтения еще ладно. Таким способом можно и несогласованные данные получить.
23 мар 16, 19:13    [18970047]     Ответить | Цитировать Сообщить модератору
 Re: Результат запроса (N строк) в скалярную переменную  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
чет я не понял юмора топика ..

select @@VERSION

DECLARE @int INT = (
    SELECT id
    FROM (
        VALUES (1), (2)
    ) t(id)
)
select @int

Results :
 
Microsoft SQL Server 2012 (SP1) - 11.0.3460.0 (X64) 
	Jul 22 2014 15:22:00 
	Copyright (c) Microsoft Corporation
	Enterprise Edition: Core-based Licensing (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1)
NULL
Messages :

(1 row(s) affected)
Msg 512, Level 16, State 1, Line 3
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

(1 row(s) affected)
24 мар 16, 10:03    [18971846]     Ответить | Цитировать Сообщить модератору
 Re: Результат запроса (N строк) в скалярную переменную  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
Maxx
чет я не понял юмора топика

Если коротко, то спрашивали как через SELECT присваивание рейсить ошибку, когда возвращается более 1 строки.
24 мар 16, 10:23    [18971912]     Ответить | Цитировать Сообщить модератору
 Re: Результат запроса (N строк) в скалярную переменную  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
AlanDenton
Если коротко, то спрашивали как через SELECT присваивание рейсить ошибку

мда господа знают толк в извращениях...
24 мар 16, 10:50    [18972012]     Ответить | Цитировать Сообщить модератору
 Re: Результат запроса (N строк) в скалярную переменную  [new]
invm
Member

Откуда: Москва
Сообщений: 9406
AlanDenton
как через SELECT присваивание рейсить ошибку, когда возвращается более 1 строки.
declare @v1 ..., ..., @vN ..., @dummy int;

select
 @v1 = ..., ..., @vN = ..., @dummy = 1 / case when count(*) over() > 1 then 0 end
from
 ...
24 мар 16, 11:03    [18972054]     Ответить | Цитировать Сообщить модератору
 Re: Результат запроса (N строк) в скалярную переменную  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
Maxx
мда господа знают толк в извращениях...

Это еще мелочи :) мне в том году клиент просил прикрутить к рассылке через Database Mail генерацию XLS файлов по 20-30 метров (+ еще ячейки разукрашивать, чтобы на айфоне было красиво смотреть) и в довесок в теле письма генерировать произвольные графики. Вот то было истинным извращением :)
24 мар 16, 11:04    [18972061]     Ответить | Цитировать Сообщить модератору
 Re: Результат запроса (N строк) в скалярную переменную  [new]
o-o
Guest
AlanDenton
Maxx
мда господа знают толк в извращениях...

Это еще мелочи :) мне в том году клиент просил прикрутить к рассылке через Database Mail генерацию XLS файлов по 20-30 метров (+ еще ячейки разукрашивать, чтобы на айфоне было красиво смотреть) и в довесок в теле письма генерировать произвольные графики. Вот то было истинным извращением :)

а давайте откроем топик извращений и будем туда постить
самые крутые хотелки или самые дебильные реализации.
а то иногда беспросветное Картинка с другого сайта.
и нет выхода из этого дерьмантина,
и объяснять им бесполезно,
и вот с кем еще поделиться, чтобы оценили изврат?
24 мар 16, 12:32    [18972555]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить