Получить NREC после вставки записи (ADO)
Модераторы: m0p3e, edward_K, Модераторы
Это потому, что теперь сработала веткаilshat писал(а):Работало нормально все и вдруг:
Cannot find either column "dbo" or the user-defined function or aggregate "dbo.uf_sys_gettablenamebycode", or the name is ambiguous.
Все теперь не работает
Код: Выделить всё
-- Нужен последний номер для инициализации счетчика NREC
if @needmax=1
Код: Выделить всё
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- Словарь БД (таблицы)
CREATE view [dbo].[v_dict_tables] as
select sys#nrec as nrec, xf$code as code, xf$name as name, (CASE WHEN xf$code<100 THEN xf$name ELSE 'T$'+xf$name END) as sysname, xf$title as note, xf$loc2 as unit, xf$flags as flags, xf$attr as attr, CAST(CASE WHEN xf$loc2='user' THEN 1 ELSE 0 END as bit) as is_temporary, CAST(CASE WHEN xf$code<100 THEN 1 ELSE 0 END as bit) as is_system, (CASE WHEN xf$flags&512>0 THEN 'J$'+LTRIM(STR(xf$code,10)) ELSE null END) as journal_table_name from x$files where xf$code>0
GO
ET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- Возвращает наименование таблицы по ее коду
CREATE function [dbo].[uf_sys_GetTableNameByCode] (
@tablecode int, -- код таблицы
@type bit=1 ) -- что возвращаем (0 - имя таблицы в словаре, 1 - имя в БД)
returns galname
as
begin
return (select (CASE WHEN @type=0 THEN name ELSE sysname END) from dbo.v_dict_tables where code=@tablecode)
end
GO
-
- Местный житель
- Сообщения: 222
- Зарегистрирован: 04 июн 2008, 14:35
- Откуда: Стерлитамак
- Контактная информация:
ошибка
Код: Выделить всё
Column, parameter, or variable #0: Cannot find data type galname.
Parameter or variable '' has an invalid data type.
galname замените на sysnameilshat писал(а):ошибкаКод: Выделить всё
Column, parameter, or variable #0: Cannot find data type galname. Parameter or variable '' has an invalid data type.
-
- Местный житель
- Сообщения: 1844
- Зарегистрирован: 29 мар 2005, 17:49
- Откуда: Ярославская область ОАО "Часовой завод Чайка" г. Углич
- Контактная информация:
По видимому нужно просто оформить, предложенную Wiruc-ом процедуру up_sys_newnrec в виде функции.
И потом она будет вставлять...
insert T$MDAOBJRLT (f$nrec,f$comment)
select
dbo.up_sys_newnrec(31937)
,case when sopr.f$tidkgal=111 then 'акт на прием услуг'
when sopr.f$tidkgal=101 then 'накладнуха на прием мц'
end
from t$soprhoz sopr
where
.....
как то пробовал специально такой скрипт на job вешать на выполнение кой каких проверок у себя. Вставка отрабатывала.
И потом она будет вставлять...
insert T$MDAOBJRLT (f$nrec,f$comment)
select
dbo.up_sys_newnrec(31937)
,case when sopr.f$tidkgal=111 then 'акт на прием услуг'
when sopr.f$tidkgal=101 then 'накладнуха на прием мц'
end
from t$soprhoz sopr
where
.....
как то пробовал специально такой скрипт на job вешать на выполнение кой каких проверок у себя. Вставка отрабатывала.
-
- Местный житель
- Сообщения: 370
- Зарегистрирован: 28 сен 2006, 15:43
- Откуда: Санкт-Петербург
- Контактная информация:
Ну это все понятно) Я ее написал, все хорошо работало, пока однажды не получил @needmax = 1. Сразу же в этом месте :
ругань на то, что exec sp_executesql не может быть выполнен внутри функции..
Код: Выделить всё
.....
set @cparam=N'@max#F$NREC binary(8) OUT, @OriginOffice int'
exec sp_executesql @csql, @cparam, @max#F$NREC OUT, @OriginOffice
if @@error<>0
......
У нас используется такая ХП для приращения нрек, офис 1.
Код: Выделить всё
CREATE PROCEDURE spNapSetNREC(@TableNameOrCode VARCHAR(80), @NewNREC VARBINARY(8))
AS
BEGIN
DECLARE @I INT, @DbName VARCHAR(50), @NeedMax INT, @TableCode INT
DECLARE @NREC0 VARBINARY(8), @NREC VARBINARY(8), @Base VARBINARY(2)
SELECT
@Base = CONVERT(VARBINARY(2), CONVERT(INT, SUBSTRING(@NewNREC, 1, 2)) & 0x8001)
SELECT
@TableCode = dbo.fnTableCode(@TableNameOrCode),
@DbName = UPPER(DB_NAME()),
@NeedMax=0,
@NREC0 = SUBSTRING(@Base, 1, 2) + SUBSTRING(0x000000000000, 1, 6),
@I = 0
SELECT
@NREC = @NREC0
EXEC master..na_getnextnrec @DbName, @TableCode, @NREC OUTPUT, @NeedMax OUTPUT
IF @NeedMax = 1
EXEC master..na_getnextnrecbymax @DbName, @TableCode, @NREC OUTPUT, @NeedMax OUTPUT, @NewNREC
ELSE
IF @NREC >= @NewNREC
PRINT 'spNAPSetNREC: NREC успешно приращен'
ELSE
BEGIN
DECLARE @Diff BIGINT, @Msg VARCHAR(8000), @IMax BIGINT
SELECT
@IMax = 1000000,
@Diff = CONVERT(BIGINT, @NewNREC) - CONVERT(BIGINT, @NREC)
IF @Diff > @IMax BEGIN
SELECT @Msg = 'spNAPSetNREC: приращение NREC на слишком большое значение (' + LTRIM(@Diff) + ')'
RAISERROR(@Msg, 16, 1)
END
ELSE BEGIN
PRINT 'spNapSetNREC: Вызываю na_getnextnrec в цикле...'
WHILE @NREC < @NewNREC AND @I <= @IMax
BEGIN
SELECT @NREC = @NREC0
EXEC master..na_getnextnrec @DbName, @TableCode, @NREC OUTPUT, @NeedMax OUTPUT
SELECT @I = @I + 1
END
IF ISNULL(@NREC, 0) < @NewNREC
BEGIN
SELECT @Msg = 'Ошибка в spNapSetNREC: ' + CHAR(10) +
'NREC не приращен до заданного значения. ' +
'Цикл прерван после ' + LTRIM(@I) + ' вызовов na_getnextnrec. ' + CHAR(10) +
'Для дополнительного приращения NREC повторно вызовите процедуру ' +
'spNapSetNREC.'
RAISERROR(@Msg, 16, 1)
END
END
END
IF @NREC = @NewNREC PRINT 'spNapSetNREC: NREC успешно приращен.'
END
GO
-
- Местный житель
- Сообщения: 1844
- Зарегистрирован: 29 мар 2005, 17:49
- Откуда: Ярославская область ОАО "Часовой завод Чайка" г. Углич
- Контактная информация:
Vik, был невнимателен я. Похоже не все так просто..)
Можно попробовать убрать ,если ты уже оформил в виде функции, в приведенном коде Wiruc-а строки :
....
declare @max#F$NREC comp, @csql nvarchar(200), @cparam nvarchar(50)
set @csql=N'SELECT @max#F$NREC=MAX(F$NREC) FROM '+dbo.uf_sys_gettablenamebycode(@tableid, 1)+N' where convert(int,substring(F$NREC,1,2))=(@OriginOffice|0x8000)'
set @cparam=N'@max#F$NREC binary( 8 ) OUT, @OriginOffice int'
exec sp_executesql @csql, @cparam, @max#F$NREC OUT, @OriginOffice
if @@error<>0
begin
exec up_sys_raisefatalerror @@procid, 'Ошибка при вызове динамик-SQL'
return 1
end
...
По идее дожно работать, но видимо без учета офисности (вернее тока для определенного офиса какого то) , как у Polimer-а ...
Можно попробовать убрать ,если ты уже оформил в виде функции, в приведенном коде Wiruc-а строки :
....
declare @max#F$NREC comp, @csql nvarchar(200), @cparam nvarchar(50)
set @csql=N'SELECT @max#F$NREC=MAX(F$NREC) FROM '+dbo.uf_sys_gettablenamebycode(@tableid, 1)+N' where convert(int,substring(F$NREC,1,2))=(@OriginOffice|0x8000)'
set @cparam=N'@max#F$NREC binary( 8 ) OUT, @OriginOffice int'
exec sp_executesql @csql, @cparam, @max#F$NREC OUT, @OriginOffice
if @@error<>0
begin
exec up_sys_raisefatalerror @@procid, 'Ошибка при вызове динамик-SQL'
return 1
end
...
По идее дожно работать, но видимо без учета офисности (вернее тока для определенного офиса какого то) , как у Polimer-а ...
-
- Местный житель
- Сообщения: 1844
- Зарегистрирован: 29 мар 2005, 17:49
- Откуда: Ярославская область ОАО "Часовой завод Чайка" г. Углич
- Контактная информация:
Еще можно попробовать выцеплять нужный @max#F$NREC
посредством view. Создаем скриптом текст вью :
select distinct 'select '+table_name+' table_name,max(f$nrec) from '+table_name+' union '
from information_schema.columns where column_name = 'f$nrec' and substring(table_name,1,2)='t$'
далее создаем create view vmaxtNrec как результат этого. И внутри функции определеяем :
@max#F$NREC =select Nrec from vmaxtNrec where table_name = 'table2'
Но это навскидку - нужно пробовать...
посредством view. Создаем скриптом текст вью :
select distinct 'select '+table_name+' table_name,max(f$nrec) from '+table_name+' union '
from information_schema.columns where column_name = 'f$nrec' and substring(table_name,1,2)='t$'
далее создаем create view vmaxtNrec как результат этого. И внутри функции определеяем :
@max#F$NREC =select Nrec from vmaxtNrec where table_name = 'table2'
Но это навскидку - нужно пробовать...
-
- Местный житель
- Сообщения: 370
- Зарегистрирован: 28 сен 2006, 15:43
- Откуда: Санкт-Петербург
- Контактная информация:
Den писал(а):Vik, был невнимателен я. Похоже не все так просто..)
Можно попробовать убрать ,если ты уже оформил в виде функции, в приведенном коде Wiruc-а строки :
...
declare @max#F$NREC comp, @csql nvarchar(200), @cparam nvarchar(50)
set @csql=N'SELECT @max#F$NREC=MAX(F$NREC) FROM '+dbo.uf_sys_gettablenamebycode(@tableid, 1)+N' where convert(int,substring(F$NREC,1,2))=(@OriginOffice|0x8000)'
set @cparam=N'@max#F$NREC binary( 8 ) OUT, @OriginOffice int'
exec sp_executesql @csql, @cparam, @max#F$NREC OUT, @OriginOffice
if @@error<>0
begin
exec up_sys_raisefatalerror @@procid, 'Ошибка при вызове динамик-SQL'
return 1
end
...
По идее дожно работать, но видимо без учета офисности (вернее тока для определенного офиса какого то) , как у Polimer-а ...
Не, убирать нельзя. Иначе будет другая ругань: Дублирование уникального ключа таблицы и так далее) Насчет вьюхи - попробую! А не подскажете, почему, когда делаю инсерт без присваивания нрека одной новой записи, запись вставляется, то есть триггер отрабатывает, а когда несколько - дублирование уникального ключа? Имею ввиду из MSSQL вставка производится.
-
- Местный житель
- Сообщения: 1844
- Зарегистрирован: 29 мар 2005, 17:49
- Откуда: Ярославская область ОАО "Часовой завод Чайка" г. Углич
- Контактная информация:
Такая вот особенность реализации это. Видимо как то связано с тем, что нреки в напе формируются, а триггер отрабатывает тогда, кода вставка фактически завершена, в частности - модифицированы индексы. Модификация уникальных индексов включает в себя
проверку, т.е. в данном случае просто проверка не пройдёт - все нреки нулевые будут, уникальность соблюдаться не будет. вообщем толком непонятно. Особенность скуля может такая еще...
В любом триггере на ins Вы увидите
-- Check and calculate new NRec value:
IF @RowCount=1 BEGIN
Т.е. если модифицируешь одну запись - то вставка пройдет. Конечно можно однострочную вставку реализовать, но хочется конечно батчем сразу (
проверку, т.е. в данном случае просто проверка не пройдёт - все нреки нулевые будут, уникальность соблюдаться не будет. вообщем толком непонятно. Особенность скуля может такая еще...
В любом триггере на ins Вы увидите
-- Check and calculate new NRec value:
IF @RowCount=1 BEGIN
Т.е. если модифицируешь одну запись - то вставка пройдет. Конечно можно однострочную вставку реализовать, но хочется конечно батчем сразу (