Страница 1 из 2

file{Prop:SQL}='INSERT INTO...'

Добавлено: 09 Декабрь 2019, 7:01
morkovin
Clarion 11. ABC. MSSQL2008.
Пытаюсь сделать "FieldPriming on Insert" в форме добавления записи.
И не получается записать в таблицу через {Prop:SQL}='INSERT INTO...'

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

  messages{PROP:SQL}='INSERT INTO Messages (mid, message,uid_fk) VALUES (CONVERT(char(36),NEWID()),null,null)'
  NEXT(messages)
  case errorcode()
  of 0 ! данные получены 
    of 33 ! данных нет
  of 90 ! ошибка SQL
        stop(fileerror() & '<10>SQL: ' & messages{PROP:SQL})
  else ! ошибка 
        stop(error() & '<10>Table: ' & name(messages))
    end
Получается какая-то ерунда. Создаётся две записи: одна с GUID и пустыми данными, другая с пустым GUID, но c данными (message, uid_fk)

запрос для SQL выполняется нормально

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

insert into messages (mid, message, uid_fk) VALUES (CONVERT(char(36), NEWID()),'1234', '1')

file{Prop:SQL}='INSERT INTO...'

Добавлено: 09 Декабрь 2019, 10:07
gromov
Не ерунда. При операции INSERT в БД добавляется пустая запись, а по завершении ввода она корректируется. Если я ничего не путаю.

file{Prop:SQL}='INSERT INTO...'

Добавлено: 09 Декабрь 2019, 10:41
kreator
next() не нужен совсем. И ещё надо посмотреть (если это в форме) настройку на автонумерацию индексов. Если в словаре нет автонумерации индексов, то форма ничего не добавляет в таблицу при открытии. Добавление идёт при нажатии на кнопку "ОК". Это проверено. Вообще какой смысл вручную делать INSERT?

file{Prop:SQL}='INSERT INTO...'

Добавлено: 09 Декабрь 2019, 11:58
Yufil
Для драйвера MS SQL надо установить параметр isIdentity для первичного ключа таблицы. Этот параметр обеспечивает корректный автоинкремент.

file{Prop:SQL}='INSERT INTO...'

Добавлено: 09 Декабрь 2019, 12:01
morkovin
kreator писал(а): 09 Декабрь 2019, 10:41 И ещё надо посмотреть (если это в форме) настройку на автонумерацию индексов. Если в словаре нет автонумерации индексов,
нет
Вообще какой смысл вручную делать INSERT?
чтобы переложить генерацию GUID на сервер. Хотел вообще задать для этого поля на сервере свойство default newid() type uniquvalified ROWID,но что-то никакого результата.

file{Prop:SQL}='INSERT INTO...'

Добавлено: 09 Декабрь 2019, 12:18
morkovin
gromov писал(а): 09 Декабрь 2019, 10:07При операции INSERT в БД добавляется пустая запись, а по завершении ввода она корректируется
т.е. надо делать

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

UPDATE messages
SET mid = convert(char(36), newid())
WHERE mid='' 

Надо попробовать

file{Prop:SQL}='INSERT INTO...'

Добавлено: 09 Декабрь 2019, 12:46
morkovin
[quote
Надо попробовать
[/quote]
Попробовал. Запрос

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

UPDATE messages SET mid=CONVERT(char(36),NEWID()) WHERE LEN(mid)=0
прекрасно выполняется в SQLExplorer.
А вот здесь:

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

    OF ?OK
      ThisWindow.Update()
      ! [Priority 7300]
      
      ! Perform field level validation
      ! [Priority 7501]
      MESSAGE(mes:mid&' - '&mes:message, 1)
[b]      messages{PROP:SQL}='UPDATE messages SET mid=CONVERT(char(36),NEWID()) WHERE LEN(mid)=0'[/b]
      NEXT(messages)  !пробовал и без этого
      ! Process 'OK' button in View Only mode
      IF SELF.Request = ViewRecord AND NOT SELF.BatchProcessing THEN
         POST(EVENT:CloseWindow)
      END
      ! [Priority 9000]
      
ничего не происходит. Явно чего не хватает - какого-нибудь PUT или Access;..Update()

file{Prop:SQL}='INSERT INTO...'

Добавлено: 09 Декабрь 2019, 13:01
Yufil
А можно посмотреть на структуру SQL-таблицы? И кларионовскую декларацию, если таковая используется

file{Prop:SQL}='INSERT INTO...'

Добавлено: 09 Декабрь 2019, 13:12
morkovin
Явно чего не хватает - какого-нибудь PUT или Access;..Update()
Получилось при таком раскладе:

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

ThisWindow.InsertAction PROCEDURE

ReturnValue          BYTE,AUTO

! Start of "WindowManager Method Data Section"
! [Priority 5000]

! End of "WindowManager Method Data Section"
  CODE
  ! Start of "WindowManager Method Executable Code Section"
  ! [Priority 2500]
  
  ! Parent Call
  ReturnValue = PARENT.InsertAction()
  ! [Priority 5001]
        messages{PROP:SQL}='UPDATE messages SET mid=CONVERT(char(36),NEWID()) WHERE LEN(mid)=0'
        Access:Messages.Update()
  
  ! End of "WindowManager Method Executable Code Section"
  RETURN ReturnValue
ThisWindow.InsertAction PROCEDURE

ReturnValue          BYTE,AUTO

! Start of "WindowManager Method Data Section"
! [Priority 5000]

! End of "WindowManager Method Data Section"
  CODE
  ! Start of "WindowManager Method Executable Code Section"
  ! [Priority 2500]
  ! Parent Call
  ReturnValue = PARENT.InsertAction()
  ! [Priority 5001]
        messages{PROP:SQL}='UPDATE messages SET mid=CONVERT(char(36),NEWID()) WHERE LEN(mid)=0'
       [b] Access:Messages.Update()[/b]
  ! End of "WindowManager Method Executable Code Section"
  RETURN ReturnValue
т. е. я перенёс точку вставки и добавил Access:...
P.S. Для чего это нужно? Для единообразия. В десктопном приложении я генерировал GUID в клиентском триггере (в словаре). Сейчас делаю доступ к БД через REST API и там типичный метод добавления записи выглядит так :

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

server.route({
    method : 'POST',
    path : '/insertMessage/{message}',
    handler : function (request, reply) {
        const message = request.params.message;   
		console.log(message);
		 var req=new sql.Request(conn);
      [b]  req.query("INSERT INTO messages (mid, message,uid_fk) VALUES (CONVERT(char(36),NEWID()),'"+message+"',1)"[/b], function (error, results, fields) {
            if (error) throw error;
            console.log(results);
            reply(results);
        });
        //reply('Yes this is MIASOFT.');
 
    }
});
Вот и захотелось унифицировать.
p.p.s. Странно, почему-то в тэге <code> нет выделения жирным шрифтом

file{Prop:SQL}='INSERT INTO...'

Добавлено: 09 Декабрь 2019, 13:19
morkovin
Yufil писал(а): 09 Декабрь 2019, 13:01А можно посмотреть на структуру SQL-таблицы? И кларионовскую декларацию, если таковая используется
Для SQL

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

USE [Abitur]
GO
/****** Object:  Table [dbo].[messages]    Script Date: 12/09/2019 14:16:08 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[messages](
	[mid] [char](36) NOT NULL,
	[message] [char](200) NULL,
	[uid_fk] [char](36) NULL
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
Думаю, это ещё не окончательный вариант

file{Prop:SQL}='INSERT INTO...'

Добавлено: 09 Декабрь 2019, 14:19
kreator
morkovin писал(а): 09 Декабрь 2019, 12:01 Хотел вообще задать для этого поля на сервере свойство default newid() type uniquvalified ROWID,но что-то никакого результата.
Я бы поработал вот с этим. Если по дефолту не получается, то в триггер таблицы SQL по Insert'у записать некий текст. ODBC-драйвер не поддерживает свойство IsIdentity, и FB изначально был туповат насчёт автонумерации, поэтому мы делаем так:

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

CREATE GENERATOR S_SPCMES;

CREATE OR ALTER TRIGGER ANUM_SPCMES FOR SPCMES
ACTIVE BEFORE INSERT POSITION 0
as
begin
  if (new.id_spc is null or new.id_spc=0) then
    new.id_spc = gen_id(s_spcmes,1);
end

file{Prop:SQL}='INSERT INTO...'

Добавлено: 09 Декабрь 2019, 15:36
morkovin
kreator писал(а): 09 Декабрь 2019, 14:19ACTIVE BEFORE INSERT POSITION 0
а вот в MS SQL нет триггера BEFORE INSERT :(

file{Prop:SQL}='INSERT INTO...'

Добавлено: 09 Декабрь 2019, 17:15
kreator
Упс! Не знал. Предлагают через Ж... Сделать триггер INSTEAD OF, там руками написать оператор Insert по значениям из таблицы inserted Впрочем, столбец первичного ключа править таким образом вряд ли получится. Да уж!!! Что-то невменяемое от Microsoft.

file{Prop:SQL}='INSERT INTO...'

Добавлено: 09 Декабрь 2019, 21:00
Yufil
А где тут первичный ключ, поднимите мне веки! Эт плохо, эт неправильно... Непонятно, как сервер будет искать свежедобавленную запись. Добавь поле и ключик Identity и пометь его в словаре. После этого можно спокойно добавлять и обновлять запись, по ключику Identitry запись будет инкрементироваться и находиться по ключу

file{Prop:SQL}='INSERT INTO...'

Добавлено: 10 Декабрь 2019, 9:32
kreator
Была речь о GUID. Никто не запрещает использовать его не для первичного ключа. Но я что-то сомневаюсь в надобности такого решения. Раз MS не даёт "before" триггеры, то должна работать "дефолтная схема". А вообще, повторюсь, странное решение у MS. Я так почитал Инет, народ мучается.