从存储过程如何获取最大数量

时间:2010-06-27 13:22:21

标签: sql-server sql-server-2008

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

在上面的过程中,我提供字段名称表名称,我想要这个字段的最大数量。为什么这不起作用?我也想要检查这些字段是否为空而不是无效。。此过程必须具有我提供的包含最大数字的字段的返回参数。请帮我修复它。

  1. 为什么这不起作用。
  2. 如何检查输入参数不为空。
  3. 如何设置输出参数

4 个答案:

答案 0 :(得分:3)

如果没有在EXEC语句中包装整个SELECT语句,则不能将字段名和表名作为参数:

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

答案 1 :(得分:2)

您不能将表名和字段名作为参数提供给存储过程。

您需要创建动态查询并使用sp_executesql执行。

您应该阅读The Curse and Blessings of Dynamic SQL

答案 2 :(得分:2)

如果始终将其用于标识列,则可以使用变量

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

否则你需要使用动态SQL(关于SQL注入的常见警告适用。)

另外,我对这背后的原因有点怀疑,除非你不担心任何并发性。

我已将参数类型更改为sysname,因为这更合适。

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

使用示例

DECLARE @id int

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


SELECT  @id

答案 3 :(得分:0)

1)由于表名的传递方式,这不起作用。

2)您只需要检查ISNULL一次,那里有多余的呼叫。

3)您不必声明输出,只需在执行存储过程时捕获返回值。

如果您尝试生成唯一ID,则这不是最好的方法,因为您可能遇到竞争条件并为其中一个呼叫生成重复的ID。理想情况下,ID已经被声明为IDENTITY列,但是如果你不能这样做,那么最好创建一个只返回ID作为IDENTITY列的特殊表。然后,您可以访问该表以获取最新版本,并确保您将获得唯一ID。

以下是没有冗余IsNull()的存储过程的工作方式。

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

AS     

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

END