SQL AnyWhere 10
J'ai besoin d'une SEQUENCE, semble que cela n'existe pas en version 10.
J'ai donc fait une fonction qui va me trouver le Premier Numéro disponible (il y a une volonté de recycler les numéros supprimés), c'est un peu différent d'une SEQUENCE, je l'avoue !
Code la fonction
je l'ai testé via
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 DROP FUNCTION GetCensureNumberSequenceNextValue; CREATE FUNCTION GetCensureNumberSequenceNextValue ( @TableName sysname, @SequenceFieldName sysname ) RETURNS INTEGER NOT DETERMINISTIC BEGIN DECLARE @cpt INTEGER; DECLARE @found INTEGER; DECLARE @newid INTEGER; DECLARE @count INTEGER; SET @newid = 0; SET @found = 0; SET @cpt = 1; EXECUTE IMMEDIATE 'SELECT COUNT(*) INTO @count FROM '||@TableName; WHILE @cpt <= @count AND @newid = 0 LOOP SET @found = 0; EXECUTE IMMEDIATE 'SELECT 1 INTO @found FROM '||@TableName||' WHERE '||@SequenceFieldName||' = @cpt'; IF @found = 0 THEN SET @newid = @cpt ELSE SET @newid = 0 END IF; SET @cpt = @cpt + 1; END LOOP; IF @newid = 0 THEN SET @newid = @cpt; END IF; RETURN @newid; END;
C'est parfait, j'ai bien un NumeroBidule avec les valeurs que j'attendais, cela bouche les trous puis cela incrémente naturellement par la suite !
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 INSERT INTO Machin(NumeroBidule, NomMachin) VALUES (GetCensureNumberSequenceNextValue ('Machin', 'NumeroBidule'), 'BOB')
D'un point de vue performance, pas de soucis, la table restera très petite et des insertions très ponctuelles !
A savoir qu'un code similaire existe dans l'application que je maintiens mais coder directement en C++ Builder (il y a autant de fois le code dupliqué qu'il doit exister de Séquence, oui c'est vilain), je voudrais uniformiser et l'intégrer directement à la Base de données
au départ mon but était de l'intégrer à un Trigger comme ceci
Mais c'est la que les choses se gatent !
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 DROP TRIGGER InsertMachinNumeroBidule; CREATE TRIGGER InsertMachinNumeroBidule AFTER INSERT ON Machin REFERENCING NEW AS NewNumeroBidule FOR EACH ROW BEGIN IF NewNumeroBidule.NumeroBidule IS NULL THEN SELECT GetCensureNumberSequenceNextValue('Machin', 'NumeroBidule') INTO NewNumeroBidule.NumeroBidule END IF; END;
Faut-il utiliser un CURSOR et mettre le code de la fonction directement dans le TRIGGER, du coup, je n'ai plus un code uniformiser et donc retour à un code dupliqué (autant le laisser en C++)Erreur ! Impossible d'insérer la ligne.
COMMIT/ROLLBACK n'est pas autorisé dans l'opération atomique
[Sybase][ODBC Driver][SQL Anywhere]COMMIT/ROLLBACK n'est pas autorisé dans l'opération atomique
SQLCODE: -267
SQLSTATE: 42000
Puis-je quand même utiliser une fonction et du SQL dynamique ?
Je n'ai pas bien compris comment récupérer le CURSOR d'un EXECUTE, j'ai trouvé un code Sybase V15 ou SQL Server 2008 qui ne fonctionne pas sous la version AnyWhere 10 !
Partager