Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Microsoft SQL Server |
![]() ![]() |
Топик располагается на нескольких страницах: [1] 2 3 вперед Ctrl→ все |
noi5e Member Откуда: Сообщений: 28 |
Задача: У нас пхп с драйвером php_mssql, который русского не понимает. Поэтому решено было отдавать параметр NAME в base64, а потом эту строку перекодировать триггером обратно. Триггер, на уровне создания на сервере - отрабатывает нормально, без ошибок. Но при добавлении данных в БД (при срабатывании триггера) пхп ругается. С ms sql работаю впервые. ( ошибка в пхп: message: SELECT failed because the following SET options have incorrect settings: 'CONCAT_NULL_YIELDS_NULL, ANSI_WARNINGS, ANSI_PADDING'. Verify that SET options are correct for use with indexed views and/or indexes on computed columns and/or filtered indexes and/or query notifications and/or XML data type methods and/or spatial index operations. (severity 16) in /domainssystem/database/mmsql.php on line 19Warning: mssql_query() [function.mssql-query]: General SQL Server error: Check messages from the SQL Server (severity 16) in /domains/system/database/mmsql.php on line 19Warning: mssql_query() [function.mssql-query]: Query failed in /domains/system/database/mmsql.php on line 19Notice: Error: SELECT failed because the following SET options have incorrect settings: 'CONCAT_NULL_YIELDS_NULL, ANSI_WARNINGS, ANSI_PADDING'. Verify that SET options are correct for use with indexed views and/or indexes on computed columns and/or filtered indexes and/or query notifications and/or XML data type methods and/or spatial index operations. select @@version: Microsoft SQL Server 2008 R2 (SP1) - 10.50.2500.0 (X64) Jun 17 2011 00:54:03 Copyright (c) Microsoft Corporation Express Edition with Advanced Services (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1) триггер: USE [db] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO SET CONCAT_NULL_YIELDS_NULL ON GO SET ANSI_WARNINGS ON GO SET ANSI_PADDING ON GO CREATE TRIGGER [dbo].[INSERTER] ON [dbo].[table] FOR INSERT AS DECLARE @source varchar(max), @decoded varchar(max), @name varchar(max) SELECT @name = NAME FROM inserted SET @source = convert(varbinary(max), @name) SET @decoded = cast('' as xml).value('xs:base64Binary(sql:variable("@name"))', 'varchar(max)') UPDATE c SET c.NAME = case(i.ID_MANAGER_MARKER) when 100 then @decoded else i.NAME end FROM dbo.table c LEFT JOIN inserted i ON c.ID = i.ID WHERE c.ID = i.ID П.С. При этом, параметры кроме ANSI_NULLS и QUOTED_IDENTIFIER, на которые ругается ms sql, я вставить не могу... При CREATE я их вписываю в триггер, но при ALTER вижу только первые 2. Возможно их где-то надо включить? П.С.С. Возможно, кто-то в курсе, как с сайта пхп (utf8) отправить русские символы в ms sql (сз1251)? iconv, почему-то, не помог. |
9 июл 13, 16:24 [14542356] Ответить | Цитировать Сообщить модератору |
noi5e Member Откуда: Сообщений: 28 |
noi5e, Конкретно строки, отвечающие за конвертацию взяты из этого примера: declare @source varbinary(max), @encoded varchar(max), @decoded varbinary(max) set @source = convert(varbinary(max), 'Hello Base64') set @encoded = cast('' as xml).value('xs:base64Binary(sql:variable("@source"))', 'varchar(max)') set @decoded = cast('' as xml).value('xs:base64Binary(sql:variable("@encoded"))', 'varbinary(max)') select convert(varchar(max), @source) as source_varchar, @source as source_binary, @encoded as encoded, @decoded as decoded_binary, convert(varchar(max), @decoded) as decoded_varchar Возможно, я как-то неверно его переделал, ибо не очень понимаю, даже прочитав о функциях convert и case, их синтаксис в таком виде... |
9 июл 13, 16:57 [14542624] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47052 |
noi5e, сколько записей может быть в inserted? |
9 июл 13, 16:59 [14542633] Ответить | Цитировать Сообщить модератору |
noi5e Member Откуда: Сообщений: 28 |
iap, Я, надеюсь, 1 =). По крайней мере 1 запись с уникальным идентификатором. |
9 июл 13, 17:05 [14542669] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47052 |
Но, во-первых, надо ожидать любое количество. Так принято. А, во-вторых, не надеяться, а хотя бы проверять на входе, раз уж не умеете обработать несколько записей. Про параметры и "вижу только первые 2" не понял, если честно. |
||
9 июл 13, 17:17 [14542736] Ответить | Цитировать Сообщить модератору |
Minamoto Member Откуда: Москва Сообщений: 1162 |
noi5e, а нельзя их и хранить в BASE64, конвертируя на уровне PHP (при чтении и записи)? Или нужно чтение из другого клиента? |
9 июл 13, 17:19 [14542755] Ответить | Цитировать Сообщить модератору |
noi5e Member Откуда: Сообщений: 28 |
iap, 1. Я могу надеяться в 2 раза лучше и больше =). А если серьезно: Можно хотя бы пример? Я на столько не понимаю в ms sql, что возможность "проверки на несколько строк" для меня звучит также, как и "обрабатывать несколько строк"... "вижу только первые 2" - оригинальное сообщение при создании триггера выглядит так, как в сабже, там присутствуют строки: "USE [db] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO SET CONCAT_NULL_YIELDS_NULL ON GO SET ANSI_WARNINGS ON GO SET ANSI_PADDING ON GO CREATE TRIGGER [dbo].[INSERTER] ON [dbo].[table] FOR INSERT AS ..." Я "выполняю" запрос. И он успешно выполняется, отчитываясь о том, что "Выполнение команд успешно завершено.". Обновляю триггер - вижу его, тыкаю "изменить" и вижу вместо строк выше, данные текст: " USE [db] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER TRIGGER [dbo].[INSERTER] ON [dbo].[table] FOR INSERT AS ... " |
9 июл 13, 17:33 [14542881] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47052 |
Если Вы впоследствии перед вставкой (перед вызовом процедуры) зададите эти параметры явно, они всё равно будут установлены в сохранённые значения перед вызовом. Если Вам нужны остальные настройки, прописывайте их прямо в триггер (после AS). Тогда его выполнение начнётся с их инициализации. |
||
9 июл 13, 17:38 [14542923] Ответить | Цитировать Сообщить модератору |
noi5e Member Откуда: Сообщений: 28 |
Minamoto, Это рассматривается как вариант решения проблемы. Другое дело, что смысл ошибки - мне неизвестен и на данном этапе я не знаю, поможет ли мне это. Вполне возможно, я неправильно понимаю, вообще, суть ошибки, но пока грешу на то, что я неправильно распоряжаюсь типами данных... Кстати, тип поля NAME в БД, куда я записываю varchar - может в этом дело? |
9 июл 13, 17:39 [14542928] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47052 |
Я даже засомневался, переустанавливаются ли эти параметры при ALTER TRIGGER. Помню, мне приходилось дропать/криэйтить процедуру, чтобы поменять QUOTED_IDENTIFIER. Но не уверен. |
9 июл 13, 17:40 [14542936] Ответить | Цитировать Сообщить модератору |
noi5e Member Откуда: Сообщений: 28 |
iap, Насчет QUOTED_IDENTIFIER не знаю... Его я сейчас не трогал. А вот AS SET CONCAT_NULL_YIELDS_NULL ON SET ANSI_WARNINGS ON SET ANSI_PADDING ON DECLARE @source varchar(max), @decoded varchar(max), @name varchar(max) Сработало и именно в alter table. Теперь видно, что триггер работает, но перекодирование не происходит =) |
9 июл 13, 17:50 [14543017] Ответить | Цитировать Сообщить модератору |
serpentariy Member Откуда: Сообщений: 265 |
|
||
9 июл 13, 18:01 [14543094] Ответить | Цитировать Сообщить модератору |
serpentariy Member Откуда: Сообщений: 265 |
|
||||
9 июл 13, 18:02 [14543102] Ответить | Цитировать Сообщить модератору |
noi5e Member Откуда: Сообщений: 28 |
Cпасибо всем за комментарии. iap написал верный комментарий. Сеты надо было вписывать после AS |
9 июл 13, 18:53 [14543355] Ответить | Цитировать Сообщить модератору |
noi5e Member Откуда: Сообщений: 28 |
Сейчас триггер выглядит так. При попытке применить его к другой таблице получаю ошибку, что для данной DML инструкции необходим OUTPUT и INTO. Почитал об этом - не понял зачем он тут и каким образом его реализовать. Помогите (.ALTER TRIGGER [db][table] FOR INSERT AS SET CONCAT_NULL_YIELDS_NULL ON SET ANSI_WARNINGS ON SET ANSI_PADDING ON DECLARE @decodename varchar(max), @name varchar(max) SELECT @name = COMPANY_NAME FROM inserted set @decodename = cast('' as xml).value('xs:base64Binary(sql:variable("@name"))', 'varbinary(max)') UPDATE c SET c.COMPANY_NAME = @decodename FROM dbo.table c LEFT JOIN inserted i ON c.ID_COMPANY = i.ID_COMPANY WHERE c.ID_COMPANY = i.ID_COMPANY |
24 июл 13, 00:11 [14607550] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47052 |
Но почему условие повторяется два раза? Причём в WHERE оно отменяет LEFT |
||
24 июл 13, 09:48 [14608367] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47052 |
iap, а что такое [db][table]??? Я бы посоветовал поставить там точку, но меня смущает аббревиатура db (а не dbo, например) |
24 июл 13, 09:52 [14608383] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47052 |
![]() Но на самом деле к noi5e |
||
24 июл 13, 09:53 [14608396] Ответить | Цитировать Сообщить модератору |
Jovanny Member Откуда: Сообщений: 1196 |
Мне кажется, корректнее как-то так.ALTER TRIGGER [dbo].[table] FOR INSERT AS SET CONCAT_NULL_YIELDS_NULL ON SET ANSI_WARNINGS ON SET ANSI_PADDING ON UPDATE c SET c.COMPANY_NAME = cast('' as xml).value('xs:base64Binary(sql:column("@name"))', 'varbinary(max)') FROM dbo.table c INNER JOIN inserted i ON c.ID_COMPANY = i.ID_COMPANY |
24 июл 13, 09:59 [14608440] Ответить | Цитировать Сообщить модератору |
Jovanny Member Откуда: Сообщений: 1196 |
Вернееc.COMPANY_NAME = cast('' as xml).value('xs:base64Binary(sql:column("name"))', 'varbinary(max)') |
24 июл 13, 10:02 [14608463] Ответить | Цитировать Сообщить модератору |
Jovanny Member Откуда: Сообщений: 1196 |
А вообще-то лучше триггер instead of использовать. Зачем Вам вставлять данные, а потом их обновлять? |
24 июл 13, 10:48 [14608832] Ответить | Цитировать Сообщить модератору |
noi5e Member Откуда: Сообщений: 28 |
В начале поста описана полная проблема: почему данный триггер вообще понадобился. Насчет Инстид оф - я пытался, но он выдает туже ошибку. |
||
24 июл 13, 12:03 [14609355] Ответить | Цитировать Сообщить модератору |
noi5e Member Откуда: Сообщений: 28 |
Если я что-то делаю с лефт джоином или вере (убираю вере, изменяю на иннер джоин), то выдает ошибку таблицы "C". дбо.табле названо так просто для вида. В другой таблице точно такой же триггер работает корректно, именно благодаря вашим прошлым советам =). А тут какая-то непонятка. На всякий случай, вот конкретно текст ошибки на сайте (при попытки сделать инсерт в эту таблицу): "Внимание: Целевая таблица "table" DML-инструкции не может иметь какие-либо активные триггеры, если инструкция содержит предложение OUTPUT без предложения INTO." |
||||
24 июл 13, 12:09 [14609411] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47052 |
noi5e, а зачем Вы в INSERTе применяете OUTPUT без вставки результата в таблицу, если имеется триггер? Перевести с русского на русский - это же так просто! Условие на правую таблицу LEFT JOINа без учёта возможного значения NULL отбрасывает всё, что прибавил LEFT JOIN к INNER JOINу. Поэтому либо переносить условие из WHERE в ON, либо убирать слово LEFT, ибо оно теряет смысл. |
24 июл 13, 12:43 [14609727] Ответить | Цитировать Сообщить модератору |
noi5e Member Откуда: Сообщений: 28 |
Могу еще вот что добавить. При переносе триггера, при его создании - была ошибка, которая не давала ВООБЩЕ создавать триггер в данной таблице (по сути - таже ошибка). При этом таблица ругалась на поле text. Я создал отдельную ячейку, указал нужный мне и рабочий (в другой таблице) тип. Таким образом я смог создать триггер, но вот ошибка на сайте - не поменялась (запрос, который делается в эту таблицу - я не вижу, к сожалению). |
24 июл 13, 12:45 [14609747] Ответить | Цитировать Сообщить модератору |
Топик располагается на нескольких страницах: [1] 2 3 вперед Ctrl→ все |
Все форумы / Microsoft SQL Server | ![]() |