Модератор: Модераторы
Mikhail писал(а):Подскажите, как модифицировать (добавлять) новые данные в таблицу через TIBDataSet (связан через DataSource с DBGrid), если он состоит из нескольких связанных таблиц. Как должен выглядеть UpdateSQL?
UPDATE MYTABLE SET
FIELD1 = :PARAM1,
FIELD2 = :PARAM2,
--и так далее
FIELDN = :PARAMN
WHERE MATABLE_ID = :PARAM_ID
*Rik* писал(а):Mikhail писал(а):Подскажите, как модифицировать (добавлять) новые данные в таблицу через TIBDataSet (связан через DataSource с DBGrid), если он состоит из нескольких связанных таблиц. Как должен выглядеть UpdateSQL?
- Код: Выделить всё
UPDATE MYTABLE SET
FIELD1 = :PARAM1,
FIELD2 = :PARAM2,
--и так далее
FIELDN = :PARAMN
WHERE MATABLE_ID = :PARAM_ID
SELECT F1, F2, F3
FROM Table1, Table2
WHERE Table2.FK_TABLE1 = TABLE1.PK_TABLE1;
UPDATE Table1, Table2
SET F1=:PARAM_F1, F2=:PARAM_F2, F3=:PARAM_F3
WHERE Table2.FK_TABLE1 = TABLE1.PK_TABLE1 AND Table2.FK_TABLE1= :PARAM_ID
Снег Север писал(а):Аналогично:
- Код: Выделить всё
UPDATE Table1, Table2
SET F1=:PARAM_F1, F2=:PARAM_F2, F3=:PARAM_F3
WHERE Table2.FK_TABLE1 = TABLE1.PK_TABLE1 AND Table2.FK_TABLE1= :PARAM_ID
Mikhail писал(а):Это понятно, а если Dataset это две таблицы связанные через внешний ключ, т.е SelectSQL такой
EXECUTE PROCEDURE MYPROC(:PARAM1, :PARAM2, :PARAM3)
Mikhail писал(а):В операторе Update можно использовать только одну таблицу.
*Rik* писал(а):Mikhail писал(а):Это понятно, а если Dataset это две таблицы связанные через внешний ключ, т.е SelectSQL такой
Сделайте хранимую процедуру для модификации и можете через неё обновлять хоть 10 таблиц одновременно.
(или EXECUTE BLOCK)
В UpdateSQL будет
- Код: Выделить всё
EXECUTE PROCEDURE MYPROC(:PARAM1, :PARAM2, :PARAM3)
Mikhail писал(а):А если все-таки это сделать это на клиенте? Как это обычно делается? На DBGrid такое просто так не получится сделать?
Т.е. форма, датасеты по числу участвующих таблиц, изменение их всех в рамках одной транзакции? Так что-ли?
*Rik* писал(а):Mikhail писал(а):А если все-таки это сделать это на клиенте? Как это обычно делается? На DBGrid такое просто так не получится сделать?
Т.е. форма, датасеты по числу участвующих таблиц, изменение их всех в рамках одной транзакции? Так что-ли?
Можно и так, если в одном запросе надо - то EXECUTE BLOCK, по другому ни как.
Mikhail писал(а):Можно пример с EXECUTE BLOCK, а то что то не получается
EXECUTE BLOCK(
CLIENT_ID BIGINT = :CLIENT_ID,
FAM VARCHAR(30) = :FAM,
IMJA VARCHAR(30) = :IMJA,
OTCH VARCHAR(30) = :OTCH,
DOM VARCHAR(10) = :DOM,
KORP VARCHAR(10) = :KORP,
KVART VARCHAR(20) = :KVART,
PINDEX VARCHAR(6) = :PINDEX,
KLADR_ID BIGINT = :KLADR_ID,
STREET_ID BIGINT = :STREET_ID,
DOP VARCHAR(50) = :DOP,
E_MAIL VARCHAR(50) = :E_MAIL,
ELDOC INTEGER = :ELDOC,
TELEFON VARCHAR(50) = :TELEFON,
ULNAIM VARCHAR(100) = :ULNAIM,
NOTZVUNION INTEGER = :NOTZVUNION)
AS
DECLARE VARIABLE SOCR VARCHAR(10);
DECLARE VARIABLE REG_SIO INTEGER;
DECLARE VARIABLE EXISTCLIENT_ID BIGINT;
DECLARE VARIABLE S VARCHAR(1000) CHARACTER SET UTF8;
DECLARE VARIABLE FIO VARCHAR(100);
BEGIN
IF (CLIENT_ID IS NULL) THEN EXCEPTION ER_PKEY;
IF ((FAM IS NULL) OR (FAM = '')) THEN EXCEPTION ER_ERROR 'Ðе указана фамилиÑ';
IF (PINDEX IS NULL) THEN EXCEPTION ER_ERROR 'Ðе указан почтовый индекÑ';
IF (NOTZVUNION IS NULL) THEN NOTZVUNION = 0;
IF (NOT EXISTS(
SELECT X.CHECKINDEX_ID FROM CHECKINDEX X WHERE X.PINDEX = :PINDEX
)) THEN EXCEPTION ER_ERROR 'Указанный Ð¸Ð½Ð´ÐµÐºÑ Ð½Ðµ принадлежит не одному почтамту';
IF (DOM = '') THEN DOM = NULL;
IF (KORP = '') THEN KORP = NULL;
IF (KVART = '') THEN KVART = NULL;
IF (E_MAIL = '') THEN E_MAIL = NULL;
IF (KLADR_ID = 0) THEN KLADR_ID = NULL;
IF (KLADR_ID IS NULL) THEN
EXCEPTION ER_ERROR 'Ðе указан адреÑ';
IF (ULNAIM = '') THEN ULNAIM = NULL;
IF (STREET_ID = 0) THEN STREET_ID = NULL;
SELECT K.SOCR, K.REG_SIO FROM KLADR K WHERE K.KLADR_ID = :KLADR_ID
INTO :SOCR, :REG_SIO;
--Ирина Петровна 17.04.13
--IF (BL = 1) THEN EXCEPTION ER_ERROR 'Ðтот Ð°Ð´Ñ€ÐµÑ Ð·Ð°Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²Ð°Ð½';
IF ((SOCR = 'РеÑп') OR (SOCR = 'край') OR (SOCR = 'обл')
OR (SOCR = 'округ') OR (SOCR = 'Ðобл') OR (SOCR = 'Ñ€-н')) THEN
EXCEPTION ER_ERROR 'Ðе корректно указан адреÑ';
/*IF (EXISTS(
SELECT C.CLIENT_ID FROM CLIENT C WHERE
C.KLADR_ID = :KLADR_ID AND C.STREET_ID = :STREET_ID AND C.DOM = :DOM
AND C.KORP = :KORP AND C.KVART = :KVART AND C.FAM = :FAM AND C.IMJA = :IMJA
)) THEN EXCEPTION ER_ERROR 'Клиент Ñ Ñ‚Ð°ÐºÐ¸Ð¼ адреÑом фамилией и именем ÑущеÑтвует';*/
FIO = FAM;
S = 'SELECT FIRST 1 CLIENT_ID FROM CLIENT WHERE FAM = ''' || :FAM || ''' AND KLADR_ID = ' || :KLADR_ID;
IF (IMJA IS NOT NULL) THEN
BEGIN
S = S || ' AND IMJA = ''' || :IMJA || '''';
FIO = FIO || ' ' || IMJA;
END
ELSE
S = S || ' AND IMJA IS NULL';
IF (OTCH IS NOT NULL) THEN
BEGIN
FIO = FIO || ' ' || OTCH;
END
IF (STREET_ID IS NOT NULL) THEN
S = S || ' AND STREET_ID = ' || :STREET_ID;
ELSE
S = S || ' AND STREET_ID IS NULL';
IF (DOM IS NOT NULL) THEN
S = S || ' AND DOM = ''' || :DOM || '''';
ELSE
S = S || ' AND DOM IS NULL';
IF (KORP IS NOT NULL) THEN
S = S || ' AND KORP = ''' || :KORP || '''';
ELSE
S = S || ' AND KORP IS NULL';
IF (KVART IS NOT NULL) THEN
S = S || ' AND KVART = ''' || :KVART || '''';
ELSE
S = S || ' AND KVART IS NULL';
EXISTCLIENT_ID = NULL;
EXECUTE STATEMENT :S INTO :EXISTCLIENT_ID;
IF (EXISTCLIENT_ID IS NOT NULL) THEN EXCEPTION ER_ERROR 'Клиент Ñ Ñ‚Ð°ÐºÐ¸Ð¼ адреÑом фамилией и именем ÑущеÑтвует';
IF (ELDOC IS NULL) THEN ELDOC = 0;
INSERT INTO CLIENT (
CLIENT_ID,
FAM,
IMJA,
OTCH,
KLADR_ID,
STREET_ID,
DOM,
KORP,
KVART,
PINDEX,
AU,
AUDATA,
DOP,
E_MAIL,
ELDOC,
TELEFON,
REG_SIO,
FIO,
ULNAIM,
NOTZVUNION)
VALUES (
:CLIENT_ID,
:FAM,
:IMJA,
:OTCH,
:KLADR_ID,
:STREET_ID,
:DOM,
:KORP,
:KVART,
:PINDEX,
CURRENT_USER,
CURRENT_TIMESTAMP,
:DOP,
:E_MAIL,
:ELDOC,
:TELEFON,
:REG_SIO,
:FIO,
:ULNAIM,
:NOTZVUNION);
END
*Rik* писал(а):Mikhail писал(а):Можно пример с EXECUTE BLOCK, а то что то не получается
Только у меня из InsertSQL:
- Код: Выделить всё
EXECUTE BLOCK(
CLIENT_ID BIGINT = :CLIENT_ID,
FAM VARCHAR(30) = :FAM,
IMJA VARCHAR(30) = :IMJA,
OTCH VARCHAR(30) = :OTCH,
DOM VARCHAR(10) = :DOM,
KORP VARCHAR(10) = :KORP,
KVART VARCHAR(20) = :KVART,
PINDEX VARCHAR(6) = :PINDEX,
KLADR_ID BIGINT = :KLADR_ID,
STREET_ID BIGINT = :STREET_ID,
DOP VARCHAR(50) = :DOP,
E_MAIL VARCHAR(50) = :E_MAIL,
ELDOC INTEGER = :ELDOC,
TELEFON VARCHAR(50) = :TELEFON,
ULNAIM VARCHAR(100) = :ULNAIM,
NOTZVUNION INTEGER = :NOTZVUNION)
AS
DECLARE VARIABLE SOCR VARCHAR(10);
DECLARE VARIABLE REG_SIO INTEGER;
DECLARE VARIABLE EXISTCLIENT_ID BIGINT;
DECLARE VARIABLE S VARCHAR(1000) CHARACTER SET UTF8;
DECLARE VARIABLE FIO VARCHAR(100);
BEGIN
IF (CLIENT_ID IS NULL) THEN EXCEPTION ER_PKEY;
IF ((FAM IS NULL) OR (FAM = '')) THEN EXCEPTION ER_ERROR 'Ðе указана фамилиÑ';
IF (PINDEX IS NULL) THEN EXCEPTION ER_ERROR 'Ðе указан почтовый индекÑ';
IF (NOTZVUNION IS NULL) THEN NOTZVUNION = 0;
IF (NOT EXISTS(
SELECT X.CHECKINDEX_ID FROM CHECKINDEX X WHERE X.PINDEX = :PINDEX
)) THEN EXCEPTION ER_ERROR 'Указанный Ð¸Ð½Ð´ÐµÐºÑ Ð½Ðµ принадлежит не одному почтамту';
IF (DOM = '') THEN DOM = NULL;
IF (KORP = '') THEN KORP = NULL;
IF (KVART = '') THEN KVART = NULL;
IF (E_MAIL = '') THEN E_MAIL = NULL;
IF (KLADR_ID = 0) THEN KLADR_ID = NULL;
IF (KLADR_ID IS NULL) THEN
EXCEPTION ER_ERROR 'Ðе указан адреÑ';
IF (ULNAIM = '') THEN ULNAIM = NULL;
IF (STREET_ID = 0) THEN STREET_ID = NULL;
SELECT K.SOCR, K.REG_SIO FROM KLADR K WHERE K.KLADR_ID = :KLADR_ID
INTO :SOCR, :REG_SIO;
--Ирина Петровна 17.04.13
--IF (BL = 1) THEN EXCEPTION ER_ERROR 'Ðтот Ð°Ð´Ñ€ÐµÑ Ð·Ð°Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²Ð°Ð½';
IF ((SOCR = 'РеÑп') OR (SOCR = 'край') OR (SOCR = 'обл')
OR (SOCR = 'округ') OR (SOCR = 'Ðобл') OR (SOCR = 'Ñ€-н')) THEN
EXCEPTION ER_ERROR 'Ðе корректно указан адреÑ';
/*IF (EXISTS(
SELECT C.CLIENT_ID FROM CLIENT C WHERE
C.KLADR_ID = :KLADR_ID AND C.STREET_ID = :STREET_ID AND C.DOM = :DOM
AND C.KORP = :KORP AND C.KVART = :KVART AND C.FAM = :FAM AND C.IMJA = :IMJA
)) THEN EXCEPTION ER_ERROR 'Клиент Ñ Ñ‚Ð°ÐºÐ¸Ð¼ адреÑом фамилией и именем ÑущеÑтвует';*/
FIO = FAM;
S = 'SELECT FIRST 1 CLIENT_ID FROM CLIENT WHERE FAM = ''' || :FAM || ''' AND KLADR_ID = ' || :KLADR_ID;
IF (IMJA IS NOT NULL) THEN
BEGIN
S = S || ' AND IMJA = ''' || :IMJA || '''';
FIO = FIO || ' ' || IMJA;
END
ELSE
S = S || ' AND IMJA IS NULL';
IF (OTCH IS NOT NULL) THEN
BEGIN
FIO = FIO || ' ' || OTCH;
END
IF (STREET_ID IS NOT NULL) THEN
S = S || ' AND STREET_ID = ' || :STREET_ID;
ELSE
S = S || ' AND STREET_ID IS NULL';
IF (DOM IS NOT NULL) THEN
S = S || ' AND DOM = ''' || :DOM || '''';
ELSE
S = S || ' AND DOM IS NULL';
IF (KORP IS NOT NULL) THEN
S = S || ' AND KORP = ''' || :KORP || '''';
ELSE
S = S || ' AND KORP IS NULL';
IF (KVART IS NOT NULL) THEN
S = S || ' AND KVART = ''' || :KVART || '''';
ELSE
S = S || ' AND KVART IS NULL';
EXISTCLIENT_ID = NULL;
EXECUTE STATEMENT :S INTO :EXISTCLIENT_ID;
IF (EXISTCLIENT_ID IS NOT NULL) THEN EXCEPTION ER_ERROR 'Клиент Ñ Ñ‚Ð°ÐºÐ¸Ð¼ адреÑом фамилией и именем ÑущеÑтвует';
IF (ELDOC IS NULL) THEN ELDOC = 0;
INSERT INTO CLIENT (
CLIENT_ID,
FAM,
IMJA,
OTCH,
KLADR_ID,
STREET_ID,
DOM,
KORP,
KVART,
PINDEX,
AU,
AUDATA,
DOP,
E_MAIL,
ELDOC,
TELEFON,
REG_SIO,
FIO,
ULNAIM,
NOTZVUNION)
VALUES (
:CLIENT_ID,
:FAM,
:IMJA,
:OTCH,
:KLADR_ID,
:STREET_ID,
:DOM,
:KORP,
:KVART,
:PINDEX,
CURRENT_USER,
CURRENT_TIMESTAMP,
:DOP,
:E_MAIL,
:ELDOC,
:TELEFON,
:REG_SIO,
:FIO,
:ULNAIM,
:NOTZVUNION);
END
Можно сделать сначала хранимую процедуру, потом перенести её в UpdateSQL исправив заголовок.
Mikhail писал(а):А set term не нужно?
Mikhail писал(а):Еще один вопрос, как получить первичный ключ (получаемый в триггере) только что вставленной строки? Нужно для вставки в подчиненную таблицу.
INSERT INTO PARENTTABLE
( ...)
VALUES
(...) RETURNING PARENTTABLE_ID INTO :PARENTTABLE_ID;
INSERT INTO CROSS
(PARENTTABLE_ID, ...) VALUES (:PARENTTABLE_ID, ....);
PARENTTABLE_ID = GEN_ID(GEN_PARENTTABLE_ID, 1);
INSERT INTO PARENTTABLE
(PARENTTABLE_ID, ...)
VALUES
(:PARENTTABLE_ID, ..)
INSERT INTO CROSS
(PARENTTABLE_ID, ...) VALUES (:PARENTTABLE_ID, ....);
INSERT INTO MYTABLE
( ...)
VALUES
(...) RETURNING MYTABLE_ID
EXECUTE Block (
CHKSTAT integer = :chkstat,
KOMMENT varchar(30) = :komment)
RETURNS (
DOCOTK_ID BIGINT)
AS
BEGIN
IF (KOMMENT = '') THEN KOMMENT = NULL;
INSERT INTO DOCOTK (
DATA,
AU,
CHKSTAT,
KOMMENT,
NEVIPOLNIMO)
VALUES (
CURRENT_DATE,
CURRENT_USER,
:CHKSTAT,
:KOMMENT,
0) RETURNING DOCOTK_ID INTO :DOCOTK_ID;
suspend;
END
*Rik* писал(а):У Вас какой IBX? В оригинальной версии это работать не будет...
Mikhail писал(а):*Rik* писал(а):У Вас какой IBX? В оригинальной версии это работать не будет...
Да пишет ошибки синтаксиса.
Firebird Express for Lazarus 1.1.0
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 74