Как мне передать существующую таблицу процедуре? Как мне использовать это … табличные параметры? посмотрите на мой код ниже, пожалуйста

#sql-server #tsql #stored-procedures #parameter-passing #table-valued-parameters

#sql-server #tsql #хранимые процедуры #передача параметров #табличные параметры

Вопрос:

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

 CREATE PROCEDURE SP_generateUniqueID ( -- pass table here somehow -- )
AS  
BEGIN
    DECLARE @ID         varchar(100)    -- NEW ID.
    DECLARE @isIDInUse  tinyint         -- BOOLEAN YES/NO.
    SET     @isIDInUse=1
    WHILE(@isIDInUse=1)                 -- KEEP GENERATING TILL YOU FIND ONE:
        BEGIN
            SET @ID= dbo.generateID('aA1a1') -- GENERATES ID. doesn't matter how.
            IF (@ID NOT IN (@passedTable))   -- DOES @ID EXIST ALREADY?
        /*(SEARCHES THE PASSED TABLE! Which its size will be 1XN)*/
                SET @isIDInUse=0             -- NO, YOU CAN USE.
        END
    RETURN @ID
END
  

Я не могу сделать так, чтобы передача существующей таблицы проходила гладко…
Я хочу иметь возможность вставлять любую таблицу, использующую идентификаторы.
Есть предложения?

Комментарии:

1. Есть несколько вариантов (CLR, динамический SQL). Но это может помочь, если вы объясните цель. С добавлением контекста у вас больше шансов получить правильное решение.

2. вы проверили табличный параметр?

3. Табличные параметры — это тупик — вы не можете просто передать таблицу, вы можете передать только табличную переменную.

4. Если вы пытаетесь сгенерировать уникальный идентификатор, почему бы вам не использовать UNIQUEIDENTIFIER с помощью NewId() или NewSequentialID() или ПОСЛЕДОВАТЕЛЬНОСТЬ. См msdn.microsoft.com/en-us/library/ms190348.aspx и msdn.microsoft.com/en-us/library/ff878091.aspx .

5. Здесь происходит ряд вещей, которые далеки от идеала. Сначала вы назвали свою процедуру с префиксом sp_ . Это не очень хорошая практика. sqlperformance.com/2012/10/t-sql-queries/sp_prefix Затем у вас есть цикл, генерирующий некоторую информацию. И внутри вашего цикла есть скалярная функция. Дополните это возможными проблемами параллелизма, и вся эта идея нуждается в переосмыслении.

Ответ №1:

Я бы посоветовал вам ДЕЙСТВИТЕЛЬНО внимательно изучить лучшие решения этой проблемы. Вы будете попадать в свою таблицу / индекс с каждой итерацией нового идентификатора, который вы генерируете. Что не так с автоинкрементным целочисленным значением:

create table IDs (ID int identity(1,1))

(кроме того, SQL Server имеет bit типы данных для логических значений. Нет необходимости в вашем tinyint )


Кроме того, единственный способ, которым, я думаю, вы можете сделать это по-своему, — это использовать динамический SQL. Используя приведенный ниже скрипт, вы должны увидеть, как вы можете передать свою schema.table в хранимую процедуру и в рамках процедуры определить, что вы ID должны быть вставлены в цикл проверки:

 create table a(ID nvarchar(100)) insert into a values('1'),('2'),('3'),('4'),('5')
create table b(ID nvarchar(100)) insert into b values('6'),('7'),('8'),('9'),('10')


declare @Table nvarchar(100) = 'dbo.a'

declare @ID nvarchar(100) = '6'
declare @IDinUse bit = 0

declare @sql nvarchar(max) = 'if exists(select ID from '   @Table   ' where ID = @ID) select @IDinUse = 1 else select @IDinUse = 0'
exec sp_executesql @sql, N'@ID nvarchar(100), @IDinUse bit output', @ID = @ID, @IDinUse = @IDinUse output
select @IDinUse as IDinUse

go

declare @Table nvarchar(100) = 'dbo.b'

declare @ID nvarchar(100) = '6'
declare @IDinUse bit = 0

declare @sql nvarchar(max) = 'if exists(select ID from '   @Table   ' where ID = @ID) select @IDinUse = 1 else select @IDinUse = 0'
exec sp_executesql @sql, N'@ID nvarchar(100), @IDinUse bit output', @ID = @ID, @IDinUse = @IDinUse output
select @IDinUse as IDinUse