|
Можно ли в SP передать в качестве параметра массив чисел ?
|
|||
---|---|---|---|
#18+
Можно ли в SP передать в качестве параметра массив чисел ? Конкретнее ситуация следующая, сохраненная продцедура возвращает отфильтрованный по различным параметрам набор записей и суммарные значения... Одним из параметров являеться поле Status tinyint, всего статусов 15 и они кодируються соответствующими числами от 0-14. Так вот можно какимто образом передать в SP статусы для фильтрации в виде {1,4,12,15} для использования в выражении WHERE a.Status IN (...), что то в этом роде ? Либо единственный способ это кодироавть необходимые статусы в int и потом както разкодироать (если да то как это лучше оформить в SP ?) Использую SQL Server 7 и клиентская часть Delphi + ADO + ADOStoredProc ... ... |
|||
:
Нравится:
Не нравится:
|
|||
26.03.2001, 17:18 |
|
Можно ли в SP передать в качестве параметра массив чисел ?
|
|||
---|---|---|---|
#18+
ну так и передавать строчкой create procedure #TestStatus @statuses varchar(100), @status int AS if ','+@statuses+',' like '%,'+convert(varchar(20),@status)+',%' print 'in' else print 'out' go exec #TestStatus '1,5,7',1 exec #TestStatus '1,5,7',5 exec #TestStatus '1,5,7',7 exec #TestStatus '1,5,7',3 ... |
|||
:
Нравится:
Не нравится:
|
|||
26.03.2001, 17:55 |
|
Можно ли в SP передать в качестве параметра массив чисел ?
|
|||
---|---|---|---|
#18+
Спасибо ! выражение ','+@statuses+',' like '%,'+convert(varchar(20),@status)+',%' работает отлично, как я понял его надо подставить в виде : WHERE (a.Status=NULL or ','+@statuses+',' like '%,'+convert(varchar(20),a.Status)+',%') and ... ? я пока не попробовал т.к. запутался с JOIN-ами Ситуация такая (надо соеденить данные из 3х таблиц): 1. LAgreements - договора (список договоров и надо получить) первичный ключ Lagr_id int (поля : AgrNum varchar(30), Status tinyint, ...) 2. LCustAgreements (клиенты участвующие в договоре и их роли в нем) в виде : Lagr_id int Cust_id int - первичный ключ в таблице Customers CustType_id int - (1-клиент,2-продавец, 3-страховщик и т.д.) 3. Таблица Customers (первичный ключ Cust_id) нужны поля CustName varchar(50) .. 4. Таблица Statuses (первичный ключ Status int) - статусы договора (надо получить поле Short varchar(5)) Надо все это объеденить в список договоров в виде : Lagr_id AgrNum Short CustName при этом чтобы была возможность фильтровать например по статусу @ststuses {1,4,5} и по клиенту (@Cust_id int и по его роли @Role int) ... примерно такая задача ! На ней я пока и споткнулся А вообще гденибудь можно почитать про правила формирования сложных JOIN для нескольких таблиц, с двумя мне все понятно а как больше получаеться какаето потонница что вначале соединять что потом ... ... |
|||
:
Нравится:
Не нравится:
|
|||
26.03.2001, 19:18 |
|
Можно ли в SP передать в качестве параметра массив чисел ?
|
|||
---|---|---|---|
#18+
А просто использовать не 1,2,3,... а 1,2,4,... Вы не хотели бы, 15 статусов вполне уложились бы в smallint, а проверка сводилась к: SELECT ... WHERE @Status & @Test_Status=@Test_Status ? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.03.2001, 21:13 |
|
Можно ли в SP передать в качестве параметра массив чисел ?
|
|||
---|---|---|---|
#18+
create procedure #TestStatus @statuses varchar(100), @custs varchar(100), @roles varchar(100) Select a.Lagr_id, a.AgrNum, s.Short, c.CustName from Lagreements a, LcustAgreements ac, Customers c, statuses s where a.lagr_id=ac.lagr_id and ac.cust_id=c.cust_id and a.status=s.status and (a.Status =’’ or ','+@statuses+',' like '%,'+convert(varchar(20),a.Status)+',%') and (c.Cust_id =’’ or ','+@custs+',' like '%,'+convert(varchar(20), c.Cust_id)+',%') and (c.Custtype =’’ or ','+@roles+',' like '%,'+convert(varchar(20), c.Custtype)+',%') Если уж хочется использовать Null, то правильней использовать IS Null, иначе при неправильной установке ansi_nulls получите неверный рез. Но при вызове процедуры без первого или второго параметров (в случае наличия последующих) придется так и писать #TestStatus null ,'2,3,4', '2,3,6'. Просто опустить можно только последний параметр, или несколько последних, напр. #TestStatus ‘3,4,5’ Если понятно как объединяются две таблицы, то с бОльшим количеством проблем быть не должно – считайте просто что после первого получили промежуточную таблицу и следующее объединение проводятся с ней и т.д. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.03.2001, 21:54 |
|
Можно ли в SP передать в качестве параметра массив чисел ?
|
|||
---|---|---|---|
#18+
Fompro : Спсибо за идею надо подумать насчет ... 1,2,4,... ", но у меня они очень много где используються эти статусы боюсь что потом будет трудно контролировать ... а может и нет ... Dmitry: А есть какой-то принцип какую таблицу ставить первой ? и вообще какое объединение считается первым самое вложенное или наоборот ? ... |
|||
:
Нравится:
Не нравится:
|
|||
27.03.2001, 14:55 |
|
Можно ли в SP передать в качестве параметра массив чисел ?
|
|||
---|---|---|---|
#18+
Кстати а какая вообще разница в выполнении запросов где используеться WHERE или вместо этого INNER JOIN ? тот же пример : Select a.Lagr_id, a.AgrNum, s.Short, c.CustName from Lagreements a, LcustAgreements ac, Customers c, statuses s WHERE a.lagr_id=ac.lagr_id and ac.cust_id=c.cust_id and a.status=s.status and (a.Status =’’ or ','+@statuses+',' like '%,'+convert(varchar(20),a.Status)+',%') and ... Имеет ли смысл делать вначале соединение таблиц как INNER JOIN а потом фильтровать используя WHERE или не какой разницы нет если все делается с помощью одного WHERE ? ... |
|||
:
Нравится:
Не нравится:
|
|||
27.03.2001, 15:12 |
|
Можно ли в SP передать в качестве параметра массив чисел ?
|
|||
---|---|---|---|
#18+
Насчет разницы между Where и Inner join... Разница чисто теоретическая. Select T1.*, T2.* from T1, T2 без WHERE делает выборку - декартово произведение записей таблиц T1 и T2. Если после этого стоит WHERE, то с точки зрения ГОЛОЙ ТЕОРИИ выборка должна отфильтровывать записи из декартового произведения. Inner join же в отличие от предыдущего варианта является четким указанием о том, какую совокупность следует выбрать из двух таблиц. На самом деле оптимизатор MS SQL Server анализирует запрос и сам превращает его в Inner join (если сможет). Это приводит к существенному увеличению производительности. Если посмотреть на план запроса по первому варианту и по второму, то выясняется, что они одинаковые. Все потому, что на момент составления плана SQL Server уже разобрался, что, собственно, от него хотят. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.03.2001, 17:10 |
|
Можно ли в SP передать в качестве параметра массив чисел ?
|
|||
---|---|---|---|
#18+
>Кстати а какая вообще разница в выполнении запросов где используеться WHERE или вместо этого INNER JOIN Если у вас в выражении Where будут стоять еще какие-либо условия, то результат запроса может быть неверным, я предпочитаю явно указывать join-ы, и смотрится понятней, и вероятность ошибки меньше ... |
|||
:
Нравится:
Не нравится:
|
|||
27.03.2001, 17:27 |
|
Можно ли в SP передать в качестве параметра массив чисел ?
|
|||
---|---|---|---|
#18+
Тоесть когда используеться INNER JOIN можно контролировать в какойто мере как будет идти объединение таблиц а при WHERE все решит обтимизатор запросов ... Значит в JOIN тоже не очень важно в какой последовательности соединять таблицы, только поля ON ... надо правильно проставить т.к. если что обтимизатор запросов все расставит по местам ? Кстати что вы скажите про такую продцедуру ее стоит переписывать с JOIN или и так будет нормально ? CREATE PROCEDURE spL_Mng_GetFiltredAgr_List @Manager varchar(25)='ALL_MANAGERS', @Statuses varchar(30)='', @Cust_id int=0, @CustType_id int=1, @SDate datetime=NULL, @EDate datetime=NULL AS IF @Manager='CURRENT_USER' SET @Manager=CURRENT_USER SELECT a.Lagr_id, a.AgrNum, a.AgrCDate, a.User_id, c.cust_name, s.Short FROM LAgreements a, LAgrStatuses s, customers c , LCustAgreements ca WHERE a.Lagr_id=ac.Lagr_id and ac.Cust_id=c.Cust_id and a.Status=s.Status and (@Statuses ='' or ','+@Statuses+',' like '%,'+convert(varchar(10),a.Status)+',%') and (@Cust_id=0 or (ac.Cust_id=@Cust_id and ac.CustType_id=@CustType_id)) and (@Manager='ALL_MANAGERS' or a.User_id=@Manager ) and (ISNULL(@SDate,1)=1 or a.AgrCDate>=@SDate) and (ISNULL(@EDate,1)=1 or a.AgrCDate<=@EDate) а если в соединение добавиться еще пара таблиц тогда тоже нормально соединиться через WHERE ? порядок того как следуют равенства в условии WHERE на что то влияет, например на производительность и т.к. или можно писать как попало ? ... |
|||
:
Нравится:
Не нравится:
|
|||
27.03.2001, 17:29 |
|
Можно ли в SP передать в качестве параметра массив чисел ?
|
|||
---|---|---|---|
#18+
Только что я обнаружил разницу в использовании WHERE и JOIN, дело в том что приведенная выше продцедура правильно не объединяет записи я получаю список из таблицы LCustAgreements 1 11111 2001-03-08 dbo DUBULTU ŠĶELDA OFR 1 11111 2001-03-08 dbo LAIMAVA OFR 1 11111 2001-03-08 dbo LAIMAVA OFR 1 11111 2001-03-08 dbo LAIMAVA OFR 1 11111 2001-03-08 dbo LAIMAVA OFR 1 11111 2001-03-08 dbo LAIMAVA OFR 2 22222 2001-03-10 dbo SERGEJS JURKEVIČS OFR 2 22222 2001-03-10 dbo SERGEJS JURKEVIČS OFR 2 22222 2001-03-10 dbo DUBULTU ŠĶELDA OFR Просто к данным добавленны значения соответствующих полей из других таблиц, а мне надо тоже самое но из таблицы LAgreements ! ... |
|||
:
Нравится:
Не нравится:
|
|||
27.03.2001, 17:44 |
|
Можно ли в SP передать в качестве параметра массив чисел ?
|
|||
---|---|---|---|
#18+
исходите из принципа "лучшее - враг хорошего" если всё работает и устраивает - не надо трогать как писать - с условиями во where или в join - больше дело вкуса, всё равно SQL будет делать по своему. Я лично стараюсь не использовать JOIN, но каких-то осознанных причин назвать не могу. Просто не нравиться. Мне кажется это не очень наглядным, на мой взляд лучше отдельно перечислить все таблицы, а потом отдельно условия. С приветом Сергей PS. 2 Genady "Если у вас в выражении Where будут стоять еще какие-либо условия, то результат запроса может быть неверным" Сильно. Я в принципе догадываюсь что Вы имели ввиду, но представьте что это читает человек который не особо искушен в SQL - что он может подумать? ... |
|||
:
Нравится:
Не нравится:
|
|||
27.03.2001, 17:51 |
|
Можно ли в SP передать в качестве параметра массив чисел ?
|
|||
---|---|---|---|
#18+
2 DenisL: Хм... Оччень интересно. Вы хотите сказать что у Вас эти запросом выбираются данные из LCustAgreements? Посмотрите еще раз повнимательней, у Вас ведь в списке выборки полей этой таблицы (алиас ca) вообще нет ... |
|||
:
Нравится:
Не нравится:
|
|||
27.03.2001, 19:48 |
|
Можно ли в SP передать в качестве параметра массив чисел ?
|
|||
---|---|---|---|
#18+
Я случайно скопировал до исправления ошибки (там алиас должен быть у LCustAgreements не ca a ac) ... Спасибо за помощи я вроде составил запрос с JOIN сам все работает ...выглядит это так : CREATE PROCEDURE spL_Mng_GetFiltredAgr_List @Manager varchar(25)='ALL_MANAGERS', @Statuses varchar(30)='', @Cust_id int=0, @CustType_id int=1, @SDate datetime=NULL, @EDate datetime=NULL AS IF @Manager='CURRENT_USER' SET @Manager=CURRENT_USER SELECT a.Lagr_id, a.AgrNum, a.AgrCDate, a.User_id, c.cust_name, s.Short FROM LAgrStatus s INNER JOIN LAgreements a ON s.Status = a.Status and (@Statuses ='' or ','+@Statuses+',' like '%,'+convert(varchar(10),a.Status)+',%') INNER JOIN LCustAgreements ac ON a.Lagr_id = ac.Lagr_id AND (ac.CustType_id = @CustType_id) INNER JOIN customers c ON ac.Cust_id = c.cust_ID and (@Cust_id=0 or (ac.Cust_id=@Cust_id)) WHERE a.Lagr_id=ac.Lagr_id and ac.Cust_id=c.Cust_id and a.Status=s.Status and (@Manager='ALL_MANAGERS' or a.User_id=@Manager ) and (ISNULL(@SDate,1)=1 or a.AgrCDate>=@SDate) and (ISNULL(@EDate,1)=1 or a.AgrCDate<=@EDate) но интересно есть всетаки какието правила в каком точно порядке ставить таблицы, и в чем отличия если я вставляю дополнительные условия к JOIN в виде .. b JOIN a ON a.id=b.id and 'доп. условие' and 'доп. усл.' JOIN ... от случая если бы я их засунул в общий WHERE ? (Дело в том что я их поставил туда где они стоят чисто интуитивно ...) ... |
|||
:
Нравится:
Не нравится:
|
|||
27.03.2001, 20:09 |
|
Можно ли в SP передать в качестве параметра массив чисел ?
|
|||
---|---|---|---|
#18+
Да нету никаких правил, потому как это абсолютно все равно! Тут ведь уже говорили что использование Join или Where абсолюно равноценно. Ну вот представь себе есть предложение Select * from tab1 join tab2 on tab1.a=tab2.a join tab3 on tab1.b=tab3.b . Так это все равно что Select * from tab1, tab2, tab3 where tab1.a=tab2 and tab1.b=tab3.b Так вот какая разница между tab1.a=tab2 and tab1.b=tab3.b и tab1.b=tab3.b and tab1.a=tab2? Правильно, никакой. Так вот и порядок объединений неважен. От перемены мест слагаемых сумма не меняется То же самое и при использовании полуобъединений (left join, right join) Только вместо "=" ,будет соответственно "*=" или "=*" Единственное что стоит сделать, когда заносишь в общий Where условие - это правильно расставить скобки если есть не только and, но и or. Чтобы на 100% не ошибиться - возьми в скобки общий where и каждое из условий объединения. (Последнее нужно только в извращенномслучае когда в оn.... тоже есть or ) ... |
|||
:
Нравится:
Не нравится:
|
|||
28.03.2001, 02:16 |
|
Можно ли в SP передать в качестве параметра массив чисел ?
|
|||
---|---|---|---|
#18+
Да, вот еще, я когда говорил про Is null, то имел ввиду именно в два слова. Т.е. конструкция ISNULL(@EDate,1)=1 конечно верная, но короче и понятнее по-моему @EDate is null Но это конечно дело вкуса ... |
|||
:
Нравится:
Не нравится:
|
|||
28.03.2001, 02:21 |
|
Можно ли в SP передать в качестве параметра массив чисел ?
|
|||
---|---|---|---|
#18+
2 SergSuper >Сильно. Я в принципе догадываюсь что Вы имели ввиду, но представьте что это читает человек который не особо искушен в SQL - что он может подумать Ну я в общем и сам не особо в нем искушен Просто мне как-то показывали примерчик, когда задаются одни и те же условия с использованием Join и where и получали разные результаты. К сожалению я пример не запомнил, сам то всегда пользуюсь join-ами, как я понимаю Вы знаете о чем речь, за примерчик буду благодарен, да и остальные нверное тоже Кстати, используя join-ы я руководствуюсь теми же соображениями что и Вы т. е. таблицы отдельно от условий для наглядности. Вот уж действительно - дело вкуса ... |
|||
:
Нравится:
Не нравится:
|
|||
28.03.2001, 11:26 |
|
Можно ли в SP передать в качестве параметра массив чисел ?
|
|||
---|---|---|---|
#18+
2 Genady Я имел ввиду другое, просто к словам прицепился Запрос может быть неправильно написан, может возвращать не то что Вам бы хотелось, но результат запроса не может быть неверным - это результат того что Вы написали. (если конечно не рассматривать залепух сервера) ... |
|||
:
Нравится:
Не нравится:
|
|||
28.03.2001, 11:41 |
|
Можно ли в SP передать в качестве параметра массив чисел ?
|
|||
---|---|---|---|
#18+
>Я имел ввиду другое, просто к словам прицепился ну неправильно выразился, давайте теперь меня бить будем А по поводу соединений таблиц, все кому интересно могут посмотреть BOL там есть раздельчик Specifying Joins in FROM or WHERE Clauses с примером. Оказалось, что ситуация не совсем такая как я думал А это цитата: The rows selected by a query are filtered first by the FROM clause join conditions, then the WHERE clause search conditions, and then the HAVING clause search conditions. Inner joins can be specified in either the FROM or WHERE clause without affecting the final result. Outer join conditions, however, may interact differently with the WHERE clause search conditions, depending on whether the join conditions are in the FROM or WHERE clause. Therefore, the ability to specify Transact-SQL outer joins in the FROM clause is not recommended, is no longer documented, and will be dropped in a future release. Все достаточно понятно объясняет. Вывод: Можно соединять таблицы любым способом, какой нравится, только нужно знать особенности ... |
|||
:
Нравится:
Не нравится:
|
|||
28.03.2001, 12:52 |
|
|
start [/forum/topic.php?desktop=1&fid=46&tid=1827119]: |
0ms |
get settings: |
8ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
24ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
50ms |
get tp. blocked users: |
2ms |
others: | 12ms |
total: | 132ms |
0 / 0 |