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

Автонумерация составного ключа в SQL таблице.

Добавлено: 21 Март 2012, 14:09
artgkx
Доброго всем здоровья!
На форуме был вопрос автонумерации составного ключа.
Для TPS все решается просто: объявляется составной ключ Unique value, Auto Number.
При Insert первое поле = поле родителя, второе поле автонумеруется в пределах подчиненности.
По крайней мере так работает в приложении и я об этом даже не задумывался.
При переводе приложения на SQL так уже не получится. Писать процедуру автонумерации
для каждого такого случая не хочется. Решил сделать функцию, которая запускалась бы на
сервере и возвращала наибольшее значение второго поля составного ключа. Но так как
с SQL только начал знаний не хватает. Поэтому прошу помощи у 'Гуру' что там не так. :oops:

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

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:		<Author,,Name>
-- Create date: <Create Date, ,>
-- Description:	<Description, ,>
-- =============================================
CREATE FUNCTION [dbo].[ufnSetNextKey] 
(
	@TblNam [varchar(50)], -- Таблица
	@FldNam1 [varchar(50)], -- 1-е поле составного ключа
	@FldNam2 [varchar(50)], -- 2-е поле составного ключа
	@ValFldNam1 [int] -- значение 1-го поля сост.ключа
)
RETURNS [int]
AS
BEGIN
	DECLARE @v_ret [int];

	@v_ret = SELECT MAX([@FldNam2]) FROM [@TblNam]
	WHERE [@TblNam].[@FldNam1] = @ValFldNam1;
	
	RETURN @v_ret; --найденное макс.значение 2-го поля сост.ключа 

END;
GO

Re: Автонумерация составного ключа в SQL таблице.

Добавлено: 21 Март 2012, 15:11
Алексей- Софт-Центр
Добрый день!
Я работаю с MySql, поэтому могут быть небольшие различия в синтаксисе операторов,
но общий принцип работы из клариона у них один.
Вам нужна не функция, а процедура с обычным
select max(...) from tabl where id=...;

а в кларионе

Clarion{prop:sql}='call '&clip(left(NameODBC))&'.GetStatus('&PRI:surpri&');'
next(clarion)

Если хотите использовать функцию, то тогда он должна вызываться из процедуры, например, добавления записи или
непосредственно из insert оператора в кларионе, типа:

Clarion{prop:sql}=' insert into tabl (pole1,pole2,...) values(значение1, ВЫЗОВ ФУНКЦИИ +1,...);'



Алексей

Re: Автонумерация составного ключа в SQL таблице.

Добавлено: 21 Март 2012, 15:38
BOB
По моему передать имя таблицы как параметр в mssql2000 не получится , может в поздних версиях и потом в данном случае вызов функции не намного короче самой функции .

Re: Автонумерация составного ключа в SQL таблице.

Добавлено: 21 Март 2012, 17:30
kreator
ИМХО для шаблонов ABC не важно таблица TPS или SQL. Всё также и проавтонумеруется. А если нужно ручной код, то можно воспользоваться стандартным методом PrimeAutoInc.

Re: Автонумерация составного ключа в SQL таблице.

Добавлено: 21 Март 2012, 22:53
Shur
Вот и я подумал, почему ж не получится?
Почитайте в help'е разделы "How to Execute Auto Incrementing on the Server using SQL" и "Server Side Auto incrementing for Clarion SQL file drivers"
А идея написания суперпроцедуры автонумерации мне почему-то совсем не нравится.

Re: Автонумерация составного ключа в SQL таблице.

Добавлено: 22 Март 2012, 10:53
Алексей- Софт-Центр
Добрый день!
ИМХО для шаблонов ABC не важно таблица TPS или SQL. Всё также и проавтонумеруется.
Я уже где-то писал, что кларион "организует" автонумерацию с помощью оператора previous для получения последнего значения ключа.
Так вот эта операция работает очень-пре-очень медленно для SQL, в отличие от TPS!!!
Поэтому: либо автонумерацию отдаем на "откуп" SQL, либо пишем простенькую хранимую процедуру, возвращающую максимальное значение ключа.


Алексей

Re: Автонумерация составного ключа в SQL таблице.

Добавлено: 22 Март 2012, 11:48
kreator
Алексей! Без обид. Если у Вас проблемы с SQL (MySQL???), это не значит, что у всех так. Автонумерация составных индексов - достаточно распространенная вещь. Неужели Вы считаете, что для каждой таблицы, для каждого такого индекса нужно писать хранимку?
ЗЫ. На крайний случай, я бы загнал нужный код в триггер.

Re: Автонумерация составного ключа в SQL таблице.

Добавлено: 22 Март 2012, 12:55
nik190994
Иногда создавал файл в котором хранил текущие значения для автонумерации...

Re: Автонумерация составного ключа в SQL таблице.

Добавлено: 23 Март 2012, 0:16
Shur
1. В MSSQL тормозов при автоинкременте раньше не замечалось. Поэтому и замеров не делали. Может TPS и быстрее. Всё же он TopSpeed, кто с ним сравнится!
2. Для MySQL, возможно, это не так. Тогда можно попробовать как и пишет SV в help'е и получать значение при помощи запроса

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

!MySQL Example
Pet FILE,DRIVER('ODBC','/AUTOINC=SELECT LAST_INSERT_ID()'),|
             OWNER('menagerie,root'),NAME('pet'),PRE(pet),BINDABLE,THREAD
3. Возвращаясь к MS SQL, такой код скорее всего не понадобится. А вот табличный индекс, конечно, лучше построить.
4. Таблица со значениями для инкремента здесь точно не подойдёт, т.к. ключ составной.
5. В качестве мнения - такие таблицы со значениями для инкремента только на первый взгляд удобны.
На самом деле они несут значительные риски и требуют обслуживания, а также считывания перед инкрементом. Наращивания до или после инкремента? -- это тоже надо решить. И в таком же духе.
6. SQL триггер. Тоже, боюсь, будет не здорово. Во всяком случае броуз скорее всего будет ошибаться с позицией вставленной строки.

Re: Автонумерация составного ключа в SQL таблице.

Добавлено: 23 Март 2012, 5:15
nik190994
Shur писал(а):4. Таблица со значениями для инкремента здесь точно не подойдёт, т.к. ключ составной.
Значение получаем посредством обращения к функции и вставляем в любое поле...
Обычно конкретное значение не важно... главное больше предыдущего...
По этой причине наращивания до или после инкремента не столь важно...
Восстановить значение инкремента очень легко посредством простой подпрограммы...

Re: Автонумерация составного ключа в SQL таблице.

Добавлено: 23 Март 2012, 9:46
Shur
Тут как бы это... Если бы конкретное значение было не важно (какая там главная задумка?),
то не зачем и составной ключ делать автоинкрементируемым.
Добавил второй ключ по ID как уникальный автоинкремент и живи себе!
А составной (с родителем и ID) будет уникальным тогда по определению.