powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Как получить одинаковый GUID
27 сообщений из 27, показаны все 2 страниц
Как получить одинаковый GUID
    #39584525
Drunik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Доброго дня, коллеги!

Возможно что-то где-то не дочитал, вопрос к тем кто дочитал. Почему вот этот запрос:

Код: sql
1.
2.
3.
4.
SELECT x.n, a.id
  FROM (SELECT NEWID() n) x
  JOIN (SELECT 1 id UNION ALL SELECT 2) a
    ON 1=1



Возвращает разные гуиды хотя по логике запрос в секции FROM должен выполняться 1 раз и должен вернуть 1 значение. Это происки оптимизатора? Никак нельзя получить одинаковый гуид без использования переменной?
...
Рейтинг: 0 / 0
Как получить одинаковый GUID
    #39584528
Фотография Maxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а план посмотреть слабо ? там все написанно.. ведь
...
Рейтинг: 0 / 0
Как получить одинаковый GUID
    #39584533
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Drunik,

Код: sql
1.
SELECT TOP (SELECT 1) NEWID()


но это вроде баг
...
Рейтинг: 0 / 0
Как получить одинаковый GUID
    #39584535
Drunik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxxа план посмотреть слабо ? там все написанно.. ведь

написанно обычно в подъезде... вот план

|--Compute Scalar(DEFINE:([Expr1000]=newid()))
|--Constant Scan(VALUES1)),((2))))

Мне от этого плана легче не стало. Я понимаю что обращение происходит к функции 2 раза - я не понимаю почему? И можно ли что то сделать чтобы это обращение делалось 1 раз?
...
Рейтинг: 0 / 0
Как получить одинаковый GUID
    #39584537
Drunik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
TaPaKDrunik,

Код: sql
1.
SELECT TOP (SELECT 1) NEWID()


но это вроде баг

Спасибо, но это тоже не помогает.
...
Рейтинг: 0 / 0
Как получить одинаковый GUID
    #39584539
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DrunikTaPaKDrunik,

Код: sql
1.
SELECT TOP (SELECT 1) NEWID()


но это вроде баг

Спасибо, но это тоже не помогает.

Код: sql
1.
2.
3.
4.
SELECT 
	(SELECT TOP (SELECT 1) NEWID())
FROM 
(SELECT 1 id UNION ALL SELECT 2 ) a
...
Рейтинг: 0 / 0
Как получить одинаковый GUID
    #39584547
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
или через джоин если хочется

Код: sql
1.
2.
3.
4.
5.
6.
7.
SELECT 
	*
FROM 
(SELECT 1 id UNION ALL SELECT 2 ) a
LEFT JOIN
(SELECT TOP (SELECT 1) NEWID() x) b
ON 1 = 1
...
Рейтинг: 0 / 0
Как получить одинаковый GUID
    #39584550
Drunik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
TaPaK,

Большое спасибо, так работает, но в голове не очень помещается.
Что такое TOP (SELECT 1) - это какая-то недекларированная фича? План запроса отличается кардинально. Очень бы хотелось узнать о такой конструкции подробнее.
...
Рейтинг: 0 / 0
Как получить одинаковый GUID
    #39584554
Drunik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я имею в виду различия плана вот с таким запросом:

Код: sql
1.
2.
3.
4.
SELECT a.id,
	(SELECT TOP (1) NEWID())
FROM 
(SELECT 1 id UNION ALL SELECT 2 ) a



А вот такой запрос всё равно не работает:

Код: sql
1.
2.
3.
4.
SELECT x.n, a.id
  FROM (SELECT TOP (SELECT 1) NEWID() n) x
  JOIN (SELECT 1 id UNION ALL SELECT 2) a
    ON 1=1



Есть ощущение что это какие-то игры оптимизатора и на какой-нибудь версии sql-сервера это всё перестанет работать (а возможно и сейчас не везде работает, проверял только на 2008 и 2014). Хотелось бы какую то теоретическую базу понять.
...
Рейтинг: 0 / 0
Как получить одинаковый GUID
    #39584558
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Drunik,

я же написал "но это вроде баг"
сейячас работает вплоть до 2016. Используйте переменную
...
Рейтинг: 0 / 0
Как получить одинаковый GUID
    #39584563
Drunik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
TaPaK,

Я понял, спасибо, будем знать.
...
Рейтинг: 0 / 0
Как получить одинаковый GUID
    #39584572
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Drunik,

Код: sql
1.
2.
3.
SELECT a.n, a.id
  FROM (SELECT NEWID() n) x cross apply
  (SELECT x.n, 1 id UNION ALL SELECT x.n, 2) a


DrunikЕсть ощущение что это какие-то игры оптимизатораАга, игры.
Сравните планы вашего запроса и моего. И обратите внимание где и сколько раз вычисляется newid().
...
Рейтинг: 0 / 0
Как получить одинаковый GUID
    #39584622
ATI.HeNRy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
First_value(newid()) over(order by (select null))
Если лень.
...
Рейтинг: 0 / 0
Как получить одинаковый GUID
    #39584668
Drunik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
invmDrunik,

Код: sql
1.
2.
3.
SELECT a.n, a.id
  FROM (SELECT NEWID() n) x cross apply
  (SELECT x.n, 1 id UNION ALL SELECT x.n, 2) a


DrunikЕсть ощущение что это какие-то игры оптимизатораАга, игры.
Сравните планы вашего запроса и моего. И обратите внимание где и сколько раз вычисляется newid().

Сломался ваш запрос на чуть более реальном примере:

Код: sql
1.
2.
3.
SELECT a.n, a.id
  FROM (SELECT NEWID() n) x 
 CROSS apply (SELECT x.n, id=number FROM master.dbo.spt_values WHERE type='P' AND number BETWEEN 1 AND 10) a



Вобщем Бог с ним с этим гуидом, не ломайте голову коллеги, я свои проблемы решил добавлением переменой - просто и надёжно.
...
Рейтинг: 0 / 0
Как получить одинаковый GUID
    #39584682
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DrunikСломался ваш запрос на чуть более реальном примереПеременная конечно надежнее. А если понадобится, например, запихнуть сей запрос в инлайновую функцию?

Суть решения - обязательная зависимость в cross apply результата внутреннего запроса от внешнего.
А в вашем чуть более реальном примере это не так.

Более правильный вариант:
Код: sql
1.
2.
3.
4.
5.
6.
7.
SELECT x.n, a.id
  FROM (SELECT NEWID() n) x cross apply
  (SELECT 1 id UNION ALL SELECT 2 where x.n >= 0x0) a
  
SELECT a.n, a.id
  FROM (SELECT NEWID() n) x 
 CROSS apply (SELECT x.n, id=number FROM master.dbo.spt_values WHERE type='P' AND number BETWEEN 1 AND 10 and x.n >= 0x0) a
...
Рейтинг: 0 / 0
Как получить одинаковый GUID
    #39584730
Drunik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
invmСуть решения - обязательная зависимость в cross apply результата внутреннего запроса от внешнего.
А в вашем чуть более реальном примере это не так.

Уважаемый invm, это всё отлично и про инлайновые функции и вьюхи вы абсолютно правы - в жизни всё требуется, но вы это где-то всё прочитали, в какой-то документации или это всё на уровне шаманства и танцев с бубнами? Интерес действительно не праздный, т.к. кроме гуидов часто встречаются запросы с обращением к какой-нибудь инлайн функции, которая вполне могла бы вызваться 1 раз, но вызывается как назло по кол-ву строк в запросе, например что то вроде такого:

Код: sql
1.
2.
declare @d datetime = getdate()
select * from Table1 where field1>dbo.func1(@d)



В такого рода запросах (более сложных) оптимизатор вдруг может делать множество обращений к func1. Если вы могли бы дать какие-то общие рекомендации, правила как этого избежать, то это, думаю, было бы полезно для многих. Конечно очень желательно всё это подкрепить какими то ссылками на документацию или статьи. Не хотелось бы при необходимости перехода на новую версию sql-сервера рвать на всех местах волосы по причине необходимости переписывания половины объектов в БД из-за того, что такая конструкция перестанет работать. В любом случае спасибо за информацию.
...
Рейтинг: 0 / 0
Как получить одинаковый GUID
    #39584898
Гигабайт Мегабайтович Килобайтов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Drunik,

знать как работает sql-сервер, а именно читать справку, ходить на курсы ))
...
Рейтинг: 0 / 0
Как получить одинаковый GUID
    #39584910
Drunik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Гигабайт Мегабайтович КилобайтовDrunik,

знать как работает sql-сервер, а именно читать справку, ходить на курсы ))

Уважаемый Гигабайт Мегабайтович, а зачем тогда нужен форум? Всё же можно прочитать в справке и походить на курсы? Я думал он нужен для обмена знаниями, видимо ошибался? Кто решает какие можно задавать вопросы на форуме, а какие нельзя? Вы?
...
Рейтинг: 0 / 0
Как получить одинаковый GUID
    #39584917
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Drunik,

простой ответ: не используйте скалярки в WHERE и тчк :)
...
Рейтинг: 0 / 0
Как получить одинаковый GUID
    #39584920
Гигабайт Мегабайтович Килобайтов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DrunikГигабайт Мегабайтович КилобайтовDrunik,

знать как работает sql-сервер, а именно читать справку, ходить на курсы ))

Уважаемый Гигабайт Мегабайтович, а зачем тогда нужен форум? Всё же можно прочитать в справке и походить на курсы? Я думал он нужен для обмена знаниями, видимо ошибался? Кто решает какие можно задавать вопросы на форуме, а какие нельзя? Вы?
ну если вы хотите на форуме про льва толстого что-бы вам процитировать всю "войну и мир " то что вы ожидаете в ответ услышать?
а что можно и что нельзя - есть в правилах форума. И также в рекомендациях.
...
Рейтинг: 0 / 0
Как получить одинаковый GUID
    #39584922
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гигабайт Мегабайтович Килобайтов,

плохо что нет рекомендации "не пуустозвонить"
...
Рейтинг: 0 / 0
Как получить одинаковый GUID
    #39584924
Drunik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
TaPaKГигабайт Мегабайтович Килобайтов,

плохо что нет рекомендации "не пуустозвонить"

Поддерживаю полностью.
TaPaK, спасибо за рекомендации!
...
Рейтинг: 0 / 0
Как получить одинаковый GUID
    #39584943
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Drunik,

если функция indeterministic, то сервер вынужден выполнить вызов ее для каждой строки. Т.е. функция при том же аргументе вернет другое значение. В том числе это системные функции даты-времени (rowguid также функция даты-времени).

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

Может это мои фантазии, надо проверять :)
...
Рейтинг: 0 / 0
Как получить одинаковый GUID
    #39584960
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гигабайт Мегабайтович КилобайтовDrunikпропущено...


Уважаемый Гигабайт Мегабайтович, а зачем тогда нужен форум? Всё же можно прочитать в справке и походить на курсы? Я думал он нужен для обмена знаниями, видимо ошибался? Кто решает какие можно задавать вопросы на форуме, а какие нельзя? Вы?
ну если вы хотите на форуме про льва толстого что-бы вам процитировать всю "войну и мир " то что вы ожидаете в ответ услышать?
а что можно и что нельзя - есть в правилах форума. И также в рекомендациях.

при всех недостатках ТС в данной теме - разве он просил "процитировать войну и мир" или всю документацию?
...
Рейтинг: 0 / 0
Как получить одинаковый GUID
    #39584964
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DrunikИнтерес действительно не праздный, т.к. кроме гуидов часто встречаются запросы с обращением к какой-нибудь инлайн функции, которая вполне могла бы вызваться 1 раз, но вызывается как назло по кол-ву строк в запросеВы путаете инлайновую со скалярной.
DrunikВ такого рода запросах (более сложных) оптимизатор вдруг может делать множество обращений к func1Это зависит от детерминированности функции, формы запроса и оптимизатора.
Пример
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
use tempdb;
go

create function dbo.fn1
(
 @x int
)
returns varchar(200)
as
begin
 return (select name from sys.objects where object_id = @x);
end;
go

create function dbo.fn2
(
 @x int
)
returns varchar(200)
as
begin
 return 'x = ' + cast(@x as varchar(10));
end;
go

create function dbo.fn3
(
 @x int
)
returns varchar(200)
with schemabinding
as
begin
 return 'x = ' + cast(@x as varchar(10));
end;
go

select objectproperty(object_id, 'IsDeterministic'), name from sys.objects where name in (N'fn1', N'fn2', N'fn3') and schema_name(schema_id)  = N'dbo';
go

select top (5) * into #t from master.dbo.spt_values;
go

set statistics xml on;

/*5 раз*/select * from #t where name = dbo.fn1(1);
/*5 раз*/select * from #t where name = dbo.fn2(1);
/*1 раз*/select * from #t where name = dbo.fn3(1);
/*1 раз*/select * from #t where name = (select dbo.fn1(1));
/*1 раз*/select * from #t where name = (select dbo.fn2(1));

declare @x int = 1;

/*5 раз*/select * from #t where name = dbo.fn1(@x);
/*5 раз*/select * from #t where name = dbo.fn2(@x);
/*1 раз*/select * from #t where name = dbo.fn3(@x);
/*5 раз*/select * from #t where name = (select dbo.fn1(@x));
/*5 раз*/select * from #t where name = (select dbo.fn2(@x));
/*1 раз*/select * from #t where name = (select dbo.fn1(@x)) option (recompile);
/*1 раз*/select * from #t where name = (select dbo.fn2(@x)) option (recompile);

set statistics xml off;
go

drop table #t;
drop function dbo.fn1, dbo.fn2, dbo.fn3;
go

...
Рейтинг: 0 / 0
Как получить одинаковый GUID
    #39585006
Drunik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
invmВы путаете инлайновую со скалярной.

да, переработал - главное что мы поняли друг друга.

invmЭто зависит от детерминированности функции, формы запроса и оптимизатора.

Большое спасибо за развёрнутый пример, про детерминированность функций всё было понятно, удивляло именно то, с какой лёгкостью через cross apply и условие, меняется способ работы оптимизатора с функцией.
Думаю что тему можно считать исчерпанной, всем спасибо!
...
Рейтинг: 0 / 0
Как получить одинаковый GUID
    #39586174
step_ks
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
27 сообщений из 27, показаны все 2 страниц
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Как получить одинаковый GUID
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]