SQL: в пункте в сохраненном procedure:how для передачи значений

Я не уверен, как физически объединить их в единственный файл, однако Вы могли использовать в некотором роде абстракцию и просто включать единственный "AllMyLibs.a/h", который в свою очередь включает все, что Вы хотите. Вы могли также поместить это в местоположение, где Ваш компилятор ищет библиотеки, таким образом, это работало бы на любой проект.

P.S. - из любопытства, почему Вам не нравится включая единственный, освобождает?

17
задан marc_s 15 June 2015 в 12:06
поделиться

4 ответа

Для SQL Server 2005 см. Erland Sommarskog '

25
ответ дан 30 November 2019 в 10:58
поделиться

вы можете использовать динамический sql. Передайте оператор in в Sql SP через переменную, объедините его в запрос в SQL и выполните с помощью sp_execute sql

create procedure myproc(@clause varchar(100)) as 
begin
  exec sp_executesql 'select * from users where userid in ( ' + @clause +' )'
end
6
ответ дан 30 November 2019 в 10:58
поделиться

Предполагая T-SQL, вы можете использовать эту прекрасную функцию (которая возвращает таблицу).

DROP FUNCTION sp_ConvertStringToTable
GO
CREATE FUNCTION sp_ConvertStringToTable(@list ntext)
      RETURNS @tbl TABLE (Position INT IDENTITY(1, 1) NOT NULL,
                          Value INT NOT NULL) AS
   BEGIN
      DECLARE @pos      int,
              @textpos  int,
              @chunklen smallint,
              @str      nvarchar(4000),
              @tmpstr   nvarchar(4000),
              @leftover nvarchar(4000)

      SET @textpos = 1
      SET @leftover = ''
      WHILE @textpos <= datalength(@list) / 2
      BEGIN
         SET @chunklen = 4000 - datalength(@leftover) / 2
         SET @tmpstr = ltrim(@leftover + substring(@list, @textpos, @chunklen))
         SET @textpos = @textpos + @chunklen

         SET @pos = charindex(' ', @tmpstr)
         WHILE @pos > 0
         BEGIN
            SET @str = substring(@tmpstr, 1, @pos - 1)
            INSERT @tbl (Value) VALUES(convert(int, @str))
            SET @tmpstr = ltrim(substring(@tmpstr, @pos + 1, len(@tmpstr)))
            SET @pos = charindex(' ', @tmpstr)
         END

         SET @leftover = @tmpstr
      END

      IF ltrim(rtrim(@leftover)) <> ''
         INSERT @tbl (Value) VALUES(convert(int, @leftover))

      RETURN
   END   
GO

Таким образом:

SELECT * FROM Users 
WHERE userid IN 
( SELECT Value FROM sp_ConvertStringToTable('1 2 3') )

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

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

РЕДАКТИРОВАТЬ: это невероятно эффективнее, чем строка конкатенация.

3
ответ дан 30 November 2019 в 10:58
поделиться

см. мой предыдущий ответ на этот

это лучший источник:

http://www.sommarskog.se/arrays-in-sql.html

создайте функцию разделения и используйте ее следующим образом:

SELECT
    *
    FROM YourTable  y
    INNER JOIN dbo.splitFunction(@Parameter) s ON y.ID=s.Value

Я предпочитаю подход с числовой таблицей

Для того, чтобы этот метод работал, вам нужно выполнить одну настройку расписания:

SELECT TOP 10000 IDENTITY(int,1,1) AS Number
    INTO Numbers
    FROM sys.objects s1
    CROSS JOIN sys.objects s2
ALTER TABLE Numbers ADD CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number)

После того, как таблица чисел настроена, создайте эту функцию:

CREATE FUNCTION [dbo].[FN_ListToTable]
(
     @SplitOn  char(1)      --REQUIRED, the character to split the @List string on
    ,@List     varchar(8000)--REQUIRED, the list to split apart
)
RETURNS TABLE
AS
RETURN 
(

    ----------------
    --SINGLE QUERY-- --this will not return empty rows
    ----------------
    SELECT
        ListValue
        FROM (SELECT
                  LTRIM(RTRIM(SUBSTRING(List2, number+1, CHARINDEX(@SplitOn, List2, number+1)-number - 1))) AS ListValue
                  FROM (
                           SELECT @SplitOn + @List + @SplitOn AS List2
                       ) AS dt
                      INNER JOIN Numbers n ON n.Number < LEN(dt.List2)
                  WHERE SUBSTRING(List2, number, 1) = @SplitOn
             ) dt2
        WHERE ListValue IS NOT NULL AND ListValue!=''

);
GO 

Теперь вы можете легко разделить строку CSV на таблицу и присоединиться к ней:

select * from dbo.FN_ListToTable(',','1,2,3,,,4,5,6777,,,')

ВЫВОД:

ListValue
-----------------------
1
2
3
4
5
6777

(6 row(s) affected)

Вы можете передать строку CSV в процедуру и обрабатывать только строки для заданных идентификаторов:

SELECT
    y.*
    FROM YourTable y
        INNER JOIN dbo.FN_ListToTable(',',@GivenCSV) s ON y.ID=s.ListValue
5
ответ дан 30 November 2019 в 10:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: