Страница 2 из 4
Добавлено: 15 окт 2008, 16:27
ilshat
Работало нормально все и вдруг:
Cannot find either column "dbo" or the user-defined function or aggregate "dbo.uf_sys_gettablenamebycode", or the name is ambiguous.
Все теперь не работает
Добавлено: 15 окт 2008, 18:38
WiRuc
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
в которой используется такая функция. Эта функция возвращает имя таблицы по ее коду банальным селектом из x$tables. Напишите сами или я вечером выложу исходник.
Добавлено: 16 окт 2008, 09:20
ilshat
Я не силен в mssql. Если не трудно выложите функцию.
Добавлено: 17 окт 2008, 01:05
WiRuc
Код: Выделить всё
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
Добавлено: 17 окт 2008, 09:28
ilshat
ошибка
Код: Выделить всё
Column, parameter, or variable #0: Cannot find data type galname.
Parameter or variable '' has an invalid data type.
Добавлено: 17 окт 2008, 12:36
WiRuc
ilshat писал(а):ошибка
Код: Выделить всё
Column, parameter, or variable #0: Cannot find data type galname.
Parameter or variable '' has an invalid data type.
galname замените на sysname
Добавлено: 27 фев 2009, 19:03
Vik
А как бы это все дело в виде функции оформить, корифеи TransactSQL не подскажут? Просто sp_executesql внутри функции работать отказывается (
Добавлено: 02 мар 2009, 11:17
Den
По видимому нужно просто оформить, предложенную 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 вешать на выполнение кой каких проверок у себя. Вставка отрабатывала.
Добавлено: 02 мар 2009, 15:33
Vik
Ну это все понятно) Я ее написал, все хорошо работало, пока однажды не получил @needmax = 1. Сразу же в этом месте :
Код: Выделить всё
.....
set @cparam=N'@max#F$NREC binary(8) OUT, @OriginOffice int'
exec sp_executesql @csql, @cparam, @max#F$NREC OUT, @OriginOffice
if @@error<>0
......
ругань на то, что exec sp_executesql не может быть выполнен внутри функции..
Добавлено: 02 мар 2009, 17:07
Polimer
У нас используется такая ХП для приращения нрек, офис 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
Добавлено: 02 мар 2009, 21:22
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-а ...
Добавлено: 03 мар 2009, 11:28
Den
Еще можно попробовать выцеплять нужный @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'
Но это навскидку - нужно пробовать...
Добавлено: 03 мар 2009, 14:49
Vik
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 вставка производится.
Добавлено: 03 мар 2009, 15:17
Den
Такая вот особенность реализации это. Видимо как то связано с тем, что нреки в напе формируются, а триггер отрабатывает тогда, кода вставка фактически завершена, в частности - модифицированы индексы. Модификация уникальных индексов включает в себя
проверку, т.е. в данном случае просто проверка не пройдёт - все нреки нулевые будут, уникальность соблюдаться не будет. вообщем толком непонятно. Особенность скуля может такая еще...
В любом триггере на ins Вы увидите
-- Check and calculate new NRec value:
IF @RowCount=1 BEGIN
Т.е. если модифицируешь одну запись - то вставка пройдет. Конечно можно однострочную вставку реализовать, но хочется конечно батчем сразу (
Добавлено: 03 мар 2009, 16:48
Den
Vik писал(а):
Не, убирать нельзя. Иначе будет другая ругань: Дублирование уникального ключа таблицы и так далее)
Хм..убрал ради интереса. Вроде чирикает все.