А скажите как правильно задействовать проверку на NULL?

Здесь обсуждаем систему TDM/PDM/Workflow Lotsia PDM PLUS (PartY PLUS).
Аватара пользователя
Александр
Активный участник
Сообщения: 1652
Зарегистрирован: 24 авг 2006, 08:06
Используемое ПО: Lotsia PDM PLUS
Откуда: 55.745578,37.665825

А скажите как правильно задействовать проверку на NULL?

Сообщение Александр »

Не подскажите...
в своих хп возвращающих строку из нескольких запросов я использую

Код: Выделить всё

SET CONCAT_NULL_YIELDS_NULL OFF	--отключить проверку NULL значений 
...
запросы
...
SET CONCAT_NULL_YIELDS_NULL ON --включить проверку NULL значений
чтобы строка была в любом случае даже когда из 10 запросов только один вернул существующее значение
а можно ли тоже самое делать в действиях или в работе
например

Код: Выделить всё

f_ExecSQLSelect_2 ('SET CONCAT_NULL_YIELDS_NULL OFF','','')
number(f_ExecSQLSelect_2 ('select rw.type_id from lsdbo.object_reference_view rw where rw.id='+string( Объект.Word_01 ),'',''))
f_ExecSQLSelect_2 ('SET CONCAT_NULL_YIELDS_NULL ON','','')
в смысле как то это на что-то повлияет если каждый юзер будет напрямую управлять настройками сервера
или есть другой путь вывода результатов нескольких запросов даже когда один из них возвращает NULL
подскажите - кто в SQL разбирается??

Софт - RicCRM<<LotsiaPDM(4.40)<<MsSQL(5/8)
Уровень администрирования - Альтернативный

Юрий
Активный участник
Сообщения: 239
Зарегистрирован: 13 янв 2005, 14:30
Используемое ПО: Lotsia PDM PLUS LT
Откуда: Украина, Донецк
Контактная информация:

Сообщение Юрий »

Для этой цели тебе может помочь представление лоции по отображению таблицы значений строковых атрибутов.
В этой таблице значение содержится в двух полях Value и Value1
Значение атрибута начиныется в первом поле и продолжается во втором. И второе поле может содержать null.

Вот как они это делают:

ALTER view [LSDBO].[value_string_view]
as
select v.id,
v.filial_id,
v.value + Coalesce(v.value1, '') as value,
v.author_id,
v.attrib_id,
v.value as value0
from lsdbo.value_string v, lsdbo.EmplDB ed
where ed.DbUser_ID = user_id() and
0 <= (select Coalesce(sum(esn.GrantS), 0)
from lsdbo.EmplStatN esn, lsdbo.EmplGroup eg
where esn.User_ID = eg.Group_ID and eg.User_ID = ed.User_ID and
esn.Action_ID = 2002000 and esn.ObjID = v.attrib_id)

Тоесть эта функция при нулевом значении поля подставляет значение из второго аргумента.
Аватара пользователя
Александр
Активный участник
Сообщения: 1652
Зарегистрирован: 24 авг 2006, 08:06
Используемое ПО: Lotsia PDM PLUS
Откуда: 55.745578,37.665825

Сообщение Александр »

т.е. ты хочешь сказать что работая с таблицей (представлением) lsdbo.attrib_value_view av, lsdbo.value_string_view vv напрямую из действия или из работы - я никогда не получу значение NULL ни при каком исходе - в крайнем случае только '' и это не помешает сцеплять строку из разных подзапросов?

Софт - RicCRM<<LotsiaPDM(4.40)<<MsSQL(5/8)
Уровень администрирования - Альтернативный

Юрий
Активный участник
Сообщения: 239
Зарегистрирован: 13 янв 2005, 14:30
Используемое ПО: Lotsia PDM PLUS LT
Откуда: Украина, Донецк
Контактная информация:

Сообщение Юрий »

Именно так. Только в данном случае, если первое поле может принимать значение null ему нужно прописать такую-же функцию и ты никогда в результате не получишь поле с null.
Аватара пользователя
Александр
Активный участник
Сообщения: 1652
Зарегистрирован: 24 авг 2006, 08:06
Используемое ПО: Lotsia PDM PLUS
Откуда: 55.745578,37.665825

Сообщение Александр »

а что лучше прописать
проверку на NULL
Coalesce(lsdbo.value_string_view,'строка - если нет значения')
но ведь как я понял.. в представлении в принципе не может быть NULL, хотя наверно и может...:roll:

или проверку на пустое значение
CoalesceEmpty(rtrim(ltrim(lsdbo.value_string_view)),'строка если значение пустое')

или и то и другое?
вобщем допустим я вывожу код +телефон +факс (3 подзапроса) и мне нужно написать

Код: Выделить всё

'Код '+ ...value.код + ' '+ ...value.телефон+ ' '+ ...value.факс
и в самом запросе понять есть ли то или иное поле и в соответствии с этим сформировать строку

Софт - RicCRM<<LotsiaPDM(4.40)<<MsSQL(5/8)
Уровень администрирования - Альтернативный

Аватара пользователя
Александр
Активный участник
Сообщения: 1652
Зарегистрирован: 24 авг 2006, 08:06
Используемое ПО: Lotsia PDM PLUS
Откуда: 55.745578,37.665825

Сообщение Александр »

все кажется понял, если нулевого значения никогда нет - то можно и через case

Код: Выделить всё

SELECT    
           (SELECT (case ltrim(rtrim(vv.value)) when '' then '' else vv.value+' ' end)
               FROM lsdbo.attrib_value_view av,
                          lsdbo.value_string_view vv 
            WHERE av.value_id = vv.id 
                         AND av.object_id = lsdbo.object_reference_view.id 
                         AND av.treelink_id = 0 
                         AND av.attrib_id = 3000000000002) + 
           lsdbo.object_reference_view.description  +

           (SELECT vv.value 
...
 FROM lsdbo.object_reference_view rw,
            lsdbo.object_type_view    
WHERE (rw.type_id = lsdbo.object_type_view.id)
             and (rw.id =4000000015666)

Софт - RicCRM<<LotsiaPDM(4.40)<<MsSQL(5/8)
Уровень администрирования - Альтернативный

Аватара пользователя
Александр
Активный участник
Сообщения: 1652
Зарегистрирован: 24 авг 2006, 08:06
Используемое ПО: Lotsia PDM PLUS
Откуда: 55.745578,37.665825

Сообщение Александр »

нет ничего не работает...
у меня первый подзапрос допуcтим выдает NULL - и вся строка сразу накрывается
и даже запись типа

Код: Выделить всё

           (SELECT (case ltrim(rtrim(Coalesce(vv.value,''))) when '' then '' else vv.value+' ' end)
               FROM lsdbo.attrib_value_view av,
                          lsdbo.value_string_view vv 
            WHERE av.value_id = vv.id 
                         AND av.object_id = rw.id 
                         AND av.treelink_id = 0 
                         AND av.attrib_id = 3000000000002)  
не спасает.....

Софт - RicCRM<<LotsiaPDM(4.40)<<MsSQL(5/8)
Уровень администрирования - Альтернативный

Юрий
Активный участник
Сообщения: 239
Зарегистрирован: 13 янв 2005, 14:30
Используемое ПО: Lotsia PDM PLUS LT
Откуда: Украина, Донецк
Контактная информация:

Сообщение Юрий »

Сформулируй задачу поточнее - что конкретно тебе нужно собрать и по каким условиям.
Аватара пользователя
Александр
Активный участник
Сообщения: 1652
Зарегистрирован: 24 авг 2006, 08:06
Используемое ПО: Lotsia PDM PLUS
Откуда: 55.745578,37.665825

Сообщение Александр »

вот конкретный запрос вывести в одну строку код+факс+телефон

Код: Выделить всё

SELECT    
           (SELECT 'Код '+vv.value 
               FROM lsdbo.attrib_value_view av,
                          lsdbo.value_string_view vv 
            WHERE av.value_id = vv.id 
                         AND av.object_id = rw.id 
                         AND av.treelink_id = 0 
                         AND av.attrib_id = 3000000000041) +
           (SELECT ' Факс '+vv.value 
               FROM lsdbo.attrib_value_view av,
                          lsdbo.value_string_view vv 
            WHERE av.value_id = vv.id 
                         AND av.object_id = rw.id 
                         AND av.treelink_id = 0 
                         AND av.attrib_id = 3000000000042) +
           (SELECT ' Телефон ' +vv.value 
               FROM lsdbo.attrib_value_view av,
                          lsdbo.value_string_view vv 
            WHERE av.value_id = vv.id 
                         AND av.object_id = rw.id 
                         AND av.treelink_id = 0 
                         AND av.attrib_id = 3000000000043) 
FROM lsdbo.object_reference_view rw,
            lsdbo.object_type_view    
WHERE (rw.type_id = lsdbo.object_type_view.id)
             and (rw.id =4000000015666)
если хоть один атрибут у данного объекта не существует то вместо строки я получаю NULL, а хотелось бы через COALESCE набрать то что есть а то чего нет забить пустыми значениями типа -''

может COALESCE не работает с подзапросами? вобщем не знаю уже что и делать

Софт - RicCRM<<LotsiaPDM(4.40)<<MsSQL(5/8)
Уровень администрирования - Альтернативный

Аватара пользователя
Александр
Активный участник
Сообщения: 1652
Зарегистрирован: 24 авг 2006, 08:06
Используемое ПО: Lotsia PDM PLUS
Откуда: 55.745578,37.665825

Сообщение Александр »

все проблема вроде решилась :wink: ненулевое значение Coalesce нужно было вперед переставить
типа

Код: Выделить всё

SELECT   
         Coalesce('тут пишем что-то если null',
           (SELECT 'Код '+vv.value
               FROM lsdbo.attrib_value_view av,
                          lsdbo.value_string_view vv
            WHERE av.value_id = vv.id
                         AND av.object_id = rw.id
                         AND av.treelink_id = 0
                         AND av.attrib_id = 3000000000041)) + 
вобщем спасибо - вопрос исчерпан
надеюсь :wink:

Софт - RicCRM<<LotsiaPDM(4.40)<<MsSQL(5/8)
Уровень администрирования - Альтернативный

Аватара пользователя
Александр
Активный участник
Сообщения: 1652
Зарегистрирован: 24 авг 2006, 08:06
Используемое ПО: Lotsia PDM PLUS
Откуда: 55.745578,37.665825

Сообщение Александр »

вобщем бред какой то, вообще не въезжаю
короче если подзапросы однозначно что то возвращают (для примера)
то функция(Coalesce('',результат запроса... в одном случае берет второй параметр в другом первый
например, при условии что все три значения есть
возвращает

Код: Выделить всё

SELECT  '"'+
   Coalesce('',(SELECT vv.value FROM lsdbo.attrib_value_view av, lsdbo.value_string_view vv 
                 WHERE av.value_id = vv.id AND av.object_id = rw.id AND av.attrib_id = 3000000000002))+
   rw.description + '"'+
   Coalesce('',(SELECT vv.value FROM lsdbo.attrib_value_view av, lsdbo.value_string_view vv 
           	 WHERE av.value_id = vv.id AND av.object_id = rw.id AND av.attrib_id = 3000000000021))
только первые два значения в кавычках (хотя третье то то же здесь)
а

Код: Выделить всё

SELECT  '"'+

   Coalesce('',(SELECT vv.value FROM lsdbo.attrib_value_view av, lsdbo.value_string_view vv 
                 WHERE av.value_id = vv.id AND av.object_id = rw.id AND av.attrib_id = 3000000000002))+
   rw.description + '"'+
   Coalesce(NULL,(SELECT vv.value FROM lsdbo.attrib_value_view av, lsdbo.value_string_view vv 
           	 WHERE av.value_id = vv.id AND av.object_id = rw.id AND av.attrib_id = 3000000000021))
возвращает все три???

а если первым параметром поставить NULL, вторым поздапрос, а третьим '' то ошибка SQL (из за последнего параметра)
и зависимости никакой поймать не могу?
выручайте....
Последний раз редактировалось Александр 29 окт 2007, 16:08, всего редактировалось 1 раз.

Софт - RicCRM<<LotsiaPDM(4.40)<<MsSQL(5/8)
Уровень администрирования - Альтернативный

Юрий
Активный участник
Сообщения: 239
Зарегистрирован: 13 янв 2005, 14:30
Используемое ПО: Lotsia PDM PLUS LT
Откуда: Украина, Донецк
Контактная информация:

Сообщение Юрий »

Электронная документация по SQL Server 2005

COALESCE (Transact-SQL)

Возвращает первое выражение из списка аргументов, не равное NULL.

Синтаксические обозначения в Transact-SQL

Синтаксис

COALESCE ( expression [ ,...n ] )


Аргументы
expression
Выражение cce77650-ce6b-4feb-9094-42409dfbeaab любого типа данных.

Типы возвращаемых данных
Возвращает тип данных аргумента в выражении expression с наиболее высоким приоритетом.

Замечания
Если все аргументы равны NULL, функция COALESCE возвращает NULL.

Примечание
По меньшей мере одно из значений NULL должно быть типизированным NULL.



Функция COALESCE(expression1,...n) является эквивалентом следующей функции CASE:

Копировать код
CASE
WHEN (expression1 IS NOT NULL) THEN expression1
...
WHEN (expressionN IS NOT NULL) THEN expressionN
ELSE NULL
END


Поведение функций ISNULL и COALESCE может быть различным, несмотря на их равнозначность. Выражение, содержащее ISNULL с параметрами, отличными от NULL, считается NOT NULL, в то время как выражения, содержащие COALESCE с параметрами, отличными от NULL, рассматриваются как NULL. В SQL Server, для индексации выражений, содержащих COALESCE с параметрами, отличными от NULL, вычисляемый столбец можно сохранить с помощью атрибута столбца PERSISTED, как в следующей инструкции:

Копировать код
CREATE TABLE #CheckSumTest
(
ID int identity ,
Num int DEFAULT ( RAND() * 100 ) ,
RowCheckSum AS COALESCE( CHECKSUM( id , num ) , 0 ) PERSISTED PRIMARY KEY
)


Примеры
В следующем примере таблица wages включает три столбца с данными о ежегодной заработной плате служащих: ежечасная оплата, жалование и комиссионные. Однако служащие получают только один тип зарплаты. Для определения общей оплаты для всех служащих используйте функцию COALESCE для получения не равных NULL значений столбцов hourly_wage, salary и commission.

Копировать код
SET NOCOUNT ON;
GO
USE master;
IF EXISTS (SELECT name FROM sys.tables
WHERE name = 'wages')
DROP TABLE wages;
GO
CREATE TABLE wages
(
emp_id tinyint identity,
hourly_wage decimal NULL,
salary decimal NULL,
commission decimal NULL,
num_sales tinyint NULL
);
GO
INSERT wages VALUES(10.00, NULL, NULL, NULL);
INSERT wages VALUES(20.00, NULL, NULL, NULL);
INSERT wages VALUES(30.00, NULL, NULL, NULL);
INSERT wages VALUES(40.00, NULL, NULL, NULL);
INSERT wages VALUES(NULL, 10000.00, NULL, NULL);
INSERT wages VALUES(NULL, 20000.00, NULL, NULL);
INSERT wages VALUES(NULL, 30000.00, NULL, NULL);
INSERT wages VALUES(NULL, 40000.00, NULL, NULL);
INSERT wages VALUES(NULL, NULL, 15000, 3);
INSERT wages VALUES(NULL, NULL, 25000, 2);
INSERT wages VALUES(NULL, NULL, 20000, 6);
INSERT wages VALUES(NULL, NULL, 14000, 4);
GO
SET NOCOUNT OFF;
GO
SELECT CAST(COALESCE(hourly_wage * 40 * 52,
salary,
commission * num_sales) AS money) AS 'Total Salary'
FROM wages;
GO


Ниже приводится результирующий набор.

Копировать код
Total Salary
------------
20800.0000
41600.0000
62400.0000
83200.0000
10000.0000
20000.0000
30000.0000
40000.0000
45000.0000
50000.0000
120000.0000
56000.0000

(12 row(s) affected)


См. также
Справочник
CASE (Transact-SQL)
ISNULL (Transact-SQL)
Системные функции (Transact-SQL)
Аватара пользователя
Александр
Активный участник
Сообщения: 1652
Зарегистрирован: 24 авг 2006, 08:06
Используемое ПО: Lotsia PDM PLUS
Откуда: 55.745578,37.665825

Сообщение Александр »

да все это видел, но как объяснить что два абсолютно идентичных подзапроса идущие один за другим по разным атрибутам
в одном случае выбирается второе значение COALESCE
а в другом первое??

Софт - RicCRM<<LotsiaPDM(4.40)<<MsSQL(5/8)
Уровень администрирования - Альтернативный

Юрий
Активный участник
Сообщения: 239
Зарегистрирован: 13 янв 2005, 14:30
Используемое ПО: Lotsia PDM PLUS LT
Откуда: Украина, Донецк
Контактная информация:

Сообщение Юрий »

Я бы на твоем месте '' ставил после выражения, а не перед.
Может в этом все дело.

Coalesce((SELECT vv.value FROM lsdbo.attrib_value_view av, lsdbo.value_string_view vv
WHERE av.value_id = vv.id AND av.object_id = rw.id AND av.attrib_id = 3000000000002). '')
Аватара пользователя
Disillusioned
Активный участник
Сообщения: 420
Зарегистрирован: 15 июл 2004, 15:12
Используемое ПО: Lotsia PDM PLUS
Откуда: Подольск
Контактная информация:

Сообщение Disillusioned »

Если написать SQL-функцию, возвращающую значение строкового атрибута, например GetStrValue(obj_id,link_id,attrib_id,default_value), то выражение суммирование строк будет выглядеть следующим образом:
GetStrValue(obj_id,link_id,attrid_id0,'')+GetStrValue(obj_id,link_id,attrid_id1,'')+...+GetStrValue(obj_id,link_id,attrid_idN,'')

P.S. default_value - значение, которое возвращает функция если значение атрибута отсутствует.
Ответить