2010-06-27 5 views
0
Create Procedure [dbo].[spGenerateID]  
(    
    @sFieldName   NVARCHAR(100), 
    @sTableName   NVARCHAR(100) 
)   
AS  
BEGIN 
    SELECT ISNULL(MAX(ISNULL(@sFieldName, 0)), 0) + 1 FROM @sTableName 
END 

Dans la procédure ci-dessus je fournir le nom du champ et nom de la table et je veux que le nombre maximum de ce champ. Pourquoi cela ne fonctionne pas? Je veux également vérifier si ces champs sont nuls que ce n'est pas un travail.. Cette procédure doit avoir un paramètre de retour du champ que j'ai fourni qui contient le nombre maximum. S'il vous plaît aidez-moi à le réparer.De procédure stockée comment obtenir le nombre maximum

  1. Pourquoi cela ne fonctionne-t-il pas?
  2. Comment vérifier le paramètre d'entrée ne sont pas null.
  3. Comment régler le paramètre de sortie

Répondre

2

Si cela est toujours utilisé pour les colonnes d'identité, vous pouvez utiliser une variable

SELECT ISNULL(IDENT_CURRENT(@sTableName),0)+1 

Sinon, vous devez utiliser SQL dynamique (les mises en garde habituelles sur l'injection SQL s'appliquent.

En outre, je suis un peu douteux sur les raisons derrière tout cela, sauf si vous n'avez aucune concurrence à s'inquiéter.

J'ai changé le type de vos paramètres en sysname car c'est plus approprié.

CREATE PROCEDURE [dbo].[spGenerateID]  
(    
    @sFieldName  sysname, 
    @sTableName  sysname, 
    @id int output 
)   
AS  
BEGIN 
DECLARE @dynsql NVARCHAR(1000) 

SET @dynsql = 'select @id =isnull(max([' + @sFieldName + ']),0)+1 from [' + @sTableName + '];' 
EXEC sp_executesql @dynsql, N'@id int output', @id OUTPUT 

END 

Exemple d'utilisation

DECLARE @id int 

EXECUTE [dbo].[spGenerateID] 
    'id' 
    ,'MYTABLE' 
    ,@id OUTPUT 


SELECT @id 
3

Vous ne pouvez pas avoir des noms de champs et les noms de table en tant que paramètres sans emballage toute l'instruction SELECT dans une instruction EXEC:

EXEC ('select isnull(max(isnull([' + @sFieldName + '],0)),0)+1 
     from [' + @sTableName + '] ') 
0

1) Ce won ne fonctionne pas à cause de la façon dont le nom de la table a été passé.

2) Il suffit de vérifier ISNULL une fois, vous y avez un nombre redondant d'appels.

3) Vous n'avez pas besoin de déclarer une sortie, il vous suffit d'attraper la valeur de retour lorsque vous exécutez la procédure stockée.

Si vous essayez de générer un identifiant unique, ce n'est pas la meilleure façon de le faire car vous pourriez rencontrer des conditions de concurrence et générer un ID dupliqué pour l'un des appels. Idéalement, l'ID est déjà déclaré en tant que colonne IDENTITY, mais si vous ne pouvez pas le faire de cette façon, il est préférable de créer une table spéciale qui renvoie simplement un ID en tant que colonne IDENTITY. Ensuite, vous pouvez accéder à cette table pour obtenir la dernière version avec l'assurance que vous obtiendrez un identifiant unique.

Voici comment votre procédure stockée peut fonctionner sans IsNull() redondant.

Create Procedure [dbo].[spGenerateID]     
    @sFieldName   NVARCHAR(100), 
    @sTableName   NVARCHAR(100)   

AS  

BEGIN 
Exec ('SELECT max(isnull(' + @sFieldName + ',0))+1 FROM ' + @sTableName) 

END 
Questions connexes