Из хранимой процедуры, как получить максимальное число - PullRequest
0 голосов
/ 27 июня 2010
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 ]

3 голосов
/ 27 июня 2010

Вы не можете иметь имена полей и имена таблиц в качестве параметров, не заключая весь оператор SELECT в оператор EXEC:

EXEC ('select  isnull(max(isnull([' + @sFieldName + '],0)),0)+1 
       from [' + @sTableName + '] ')
2 голосов
/ 27 июня 2010

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

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

В противном случае вам нужно использовать динамический SQL (применяются обычные предостережения относительно внедрения SQL).Кроме того, я все равно сомневаюсь в причинах этого, если только у вас нет проблем с параллелизмом.

Я изменил тип ваших параметров на sysname, поскольку это более уместно.1009 *

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
2 голосов
/ 27 июня 2010

Вы не можете предоставить имя таблицы и имя поля в качестве параметров хранимой процедуры.

Вам необходимо создать динамический запрос и выполнить его с помощью sp_executesql .

Вы должны прочитать Проклятие и благословения динамического SQL

0 голосов
/ 27 июня 2010

1) Это не сработает из-за способа передачи имени таблицы.

2) Вы должны проверить ISNULL только один раз, у вас там избыточное количество звонков.

3) Вам необязательно объявлять вывод, просто перехватывайте возвращаемое значение при выполнении хранимой процедуры.

Если вы пытаетесь сгенерировать уникальный идентификатор, это не лучший способ сделать это, поскольку вы можете столкнуться с условиями гонки и сгенерировать дубликат идентификатора для одного из вызовов. В идеале идентификатор уже объявлен как столбец IDENTITY, но если вы не можете сделать это таким образом, лучше создать специальную таблицу, которая просто возвращает идентификатор в виде столбца IDENTITY. Затем вы можете получить доступ к этой таблице, чтобы получить последнюю версию, гарантируя, что вы получите уникальный идентификатор.

Вот как ваша хранимая процедура может работать без избыточного IsNull ().

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

AS     

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

END
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...