Модераторы: Akina
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблема с OPENQUERY 
V
    Опции темы
DEER
Дата 23.5.2008, 10:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 749
Регистрация: 12.4.2005
Где: г. Рязань

Репутация: нет
Всего: 13



вот с такой проблемой столкнулся
Есть сервер Postgres 
на нем есть табличка
Код

CREATE TABLE test
(
  "value" text
)

Также есть функция, вставляет в эту таблицу строку из параметра
Код

CREATE OR REPLACE FUNCTION get_test(text)
  RETURNS bigint AS
$BODY$
DECLARE    
    new_v ALIAS FOR $1;    
BEGIN
INSERT INTO test (value) VALUES (new_v);
RETURN COUNT(*) FROM test;
END
$BODY$
  LANGUAGE 'plpgsql' VOLATILE
  COST 100;


на MS SQL Server есть соединение с этой БД и используя его вызывается эта фнукция
Код

select  * from OPENQUERY(PostgreSQL, ' SELECT get_test(''2'')')

так вот. Этот вызов отрабатывает !!!ДВА!!! раза (в таблице появляется две записи) если поменять параметр у функции,
то есть первый вызов - в таблице две записи "2", второй вызов - в таблице три записи "2" (отработало один раз)

Не подскажbте почнему так может происходить, и как от этого избавиться (чтобы всегда один раз вызов функции был) ?

Это сообщение отредактировал(а) DEER - 23.5.2008, 10:56


--------------------
 
PM MAIL WWW ICQ MSN   Вверх
Magnifico
Дата 23.5.2008, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 418
Регистрация: 23.1.2008
Где: Московская област ь

Репутация: 10
Всего: 17



Код

EXEC master.dbo.sp_addlinkedserver @server = N'postgre', @srvproduct=N'{PostgreSQL ANSI}', 
    @provider=N'MSDASQL', @provstr=N'Driver={PostgreSQL ANSI};uid=postgres;Server=127.0.0.1;Port=5433;database=postgres;pwd=098poi'


---в  Postgrese -------------
Код

CREATE TABLE test
(
  myvalue text,
  currtime timestamp
)

CREATE OR REPLACE FUNCTION get_test(text)
  RETURNS void AS 
$BODY$
DECLARE    
    new_v ALIAS FOR $1;  
    curtime timestamp;
    
BEGIN
curtime := 'now';
INSERT INTO test (myvalue,currtime) VALUES (new_v,curtime);
return;
END
$BODY$
  LANGUAGE 'plpgsql' VOLATILE

 
долго не мог понять вроде в постгерсе все нормально а с  опенквери  то по 2  то по 3 значнеия заносит

я изменил поле value на myvalue вроде как value зарезервированное слово

Добавлено через 8 минут и 53 секунды
опс! но если персоздать таблицу и функцию опять то же самое , наверно проблема с провайдером


--------------------
Всё  в  порядке   -   спасибо  зарядке  !
PM MAIL   Вверх
DEER
Дата 23.5.2008, 13:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 749
Регистрация: 12.4.2005
Где: г. Рязань

Репутация: нет
Всего: 13



нарыл вот такую цитату
Цитата

Запрост выполняется 2 раза 
План запроса _внутри OPENQUERY_ MSSQL безразличен. Потому, что он его не выполняет, а лишь передает linked server-у. И ждет от него результата. А для ожидания и размещения этого результата MSSQL не нужны никакие хинты и статистики

Так зачем же Он 2 раза передает linked server-у этот запрос?!!!

Сначала MSSQL должен узнать метаданные, т.е. сколько столбцов и какого типа вернется. А потом уже собственно передать запрос на выполнение.
план попадает все что снаружи OPENQUERY. Все, что стоит внутри OPENQUERY - это уже некий встроенный механизм. Что, как и в какой последовательности он делает с текстом запроса достоверно известно только создателям MSSQL.

то есть это всё правильно, что два раза выполняется, но интересно, можно ли как то это дело запретить?
может в настройках провайдера, или же при создании Linked Server  smile 


--------------------
 
PM MAIL WWW ICQ MSN   Вверх
Magnifico
Дата 23.5.2008, 14:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 418
Регистрация: 23.1.2008
Где: Московская област ь

Репутация: 10
Всего: 17



сделать внутри функции обработчик на проверку сущ. строки
Код

CREATE OR REPLACE FUNCTION get_test(text)
 RETURNS bigint AS 
$BODY$
DECLARE    
    new_v ALIAS FOR $1;  
    curtime timestamp;
    flag int;
 BEGIN
curtime := 'now';
select count(myvalue) into flag from test where myvalue = new_v;
 IF flag >0 THEN
    return 0;   
 END IF;
INSERT INTO test (myvalue,currtime) VALUES (new_v,curtime);
RETURN COUNT(*) FROM test;
END;
$BODY$
  LANGUAGE 'plpgsql'


Это сообщение отредактировал(а) Magnifico - 23.5.2008, 14:26


--------------------
Всё  в  порядке   -   спасибо  зарядке  !
PM MAIL   Вверх
DEER
Дата 23.5.2008, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 749
Регистрация: 12.4.2005
Где: г. Рязань

Репутация: нет
Всего: 13



да. пока у меня это единственный вариант который пришел в голову.
только немного не так 
Цитата

завести табличку transactions
во все наши функции добавить ещё один параметр transaction_id 
при вызове функции:
проверять есть ли в табличке такой id уже. если есть, то нифига не делать
если нету, то записывать в эту табличку новый ID и потом выполнять фукнкцию.
а уникальность этого transaction_id обеспечивать со стороны MS SQL

Код

select count(myvalue) into flag from test where myvalue = new_v;

прикольная форма записи - раньше не встречал. smile

Добавлено через 36 секунд
Спасибо за участие!


--------------------
 
PM MAIL WWW ICQ MSN   Вверх
DEER
Дата 27.5.2008, 09:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 749
Регистрация: 12.4.2005
Где: г. Рязань

Репутация: нет
Всего: 13



Проблема разрешилась изменением типа, возвращающего функцией. ТО есть тип должен быть не каким то особенным (вместо bigint постгриса потавили обычный integer)
Код

CREATE OR REPLACE FUNCTION get_test(text)
  RETURNS integer AS
$BODY$
DECLARE    
    new_v ALIAS FOR $1;    
BEGIN
INSERT INTO test (value) VALUES (new_v);
RETURN COUNT(*) FROM test;
END
$BODY$
  LANGUAGE 'plpgsql' VOLATILE
  COST 100;



--------------------
 
PM MAIL WWW ICQ MSN   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "MS SQL"
Akina

Akina

Запрещается!

Публиковать ссылки и обсуждать взлом чего бы то ни было.

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы составления неспецифических запросов рассматриваются здесь
  • Используйте теги [code=sql][/code] для подсветки кода. Используйтe чекбокс "транслит" (возле кнопок кодов) если у Вас нет русских шрифтов.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Zloxa, Akina.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | MS SQL Server | Следующая тема »


 




[ Время генерации скрипта: 0.0449 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.