SQL Server - вопрос о хранимой процедуре - PullRequest
1 голос
/ 12 января 2010

Для приложения, над которым я работаю ... мы создаем собственную систему регистрации. Пользователь может просматривать журналы и применять к ним «теги» (точно так же, как вы можете применять теги к вопросам здесь!)

В этом примере я пытаюсь получить список всех журналов, которым присвоен «тег». Я понимаю, что могу сделать это, используя соединения ... но это также упражнение для меня, чтобы выучить хранимые процедуры немного лучше:)

У меня есть хранимая процедура, которая выглядит примерно так, чтобы выбрать журнал с помощью PK

ALTER PROCEDURE [dbo].[getLogByLogId] 
    -- Add the parameters for the stored procedure here
    @ID int

AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for procedure here
    SELECT  TOP 1

    LOG_ID,
    a.A,
    a.B,
    a.C

    FROM dbo.LOG a
    WHERE a.LOG_ID = @ID

Теперь я хотел бы вызвать эту хранимую процедуру из другого ... как-то так

ALTER PROCEDURE [dbo].[getLogsByTagName] 
        -- Add the parameters for the stored procedure here
        @TAG nvarchar(50)

AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for procedure here
    SELECT  TOP 1000

    LOG_ID --somehow store this and execute the dbo.getLogByLogId procedure here

    FROM dbo.LOG_TAG a
    WHERE a.TAG = @TAG

Спасибо

Ответы [ 4 ]

2 голосов
/ 12 января 2010

Если в вашем logbyid SP есть сложная логика, которую вы пытаетесь избежать воспроизведения в нескольких местах вашей системы (выбор столбцов, производные столбцы и т. Д.), Я бы рекомендовал вместо этого превратить ее во встроенную табличную функцию ( потенциально без принятия параметра ID, в этом случае вы можете использовать обычное представление).

Затем вы можете присоединиться к этому ITVF / представлению в своем другом сохраненном процессе (или также создать другой udf), который выполняет поиск, или использовать функцию OUTER APPLY (не так эффективно).

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

0 голосов
/ 12 января 2010

Единственный способ добиться того, что вы пытаетесь - это использовать CURSOR .

Если это только для вашего обучения, то обязательно сделайте это, но я бы не рекомендовал это для производства.

Было бы что-то вроде этого

DECLARE @Table TABLE(
        ID INT
)

INSERT INTO @Table SELECT 1
INSERT INTO @Table SELECT 2
INSERT INTO @Table SELECT 3
INSERT INTO @Table SELECT 4
INSERT INTO @Table SELECT 5
INSERT INTO @Table SELECT 6


DECLARE Cur CURSOR FOR 
SELECT ID
FROM @Table

OPEN Cur

DECLARE @ID INT
FETCH NEXT FROM Cur INTO @ID

WHILE @@FETCH_STATUS = 0 
BEGIN
    PRINT @ID
    FETCH NEXT FROM Cur INTO @ID
END

CLOSE Cur
DEALLOCATE Cur

Используя @ ID , извлеченный в цикле WHILE , вы можете выполнить желаемую процедуру sp и вставить значения в табличную переменную .

INSERT INTO @Table EXEC sp_MySP @ID
0 голосов
/ 12 января 2010

Вы можете вызвать хранимую процедуру из другой, используя следующий синтаксис:

    ALTER PROCEDURE [dbo].[getLogsByTagName]  
            -- Add the parameters for the stored procedure here 
            @TAG nvarchar(50) 

    AS 
    BEGIN 
        -- SET NOCOUNT ON added to prevent extra result sets from 
        -- interfering with SELECT statements. 
        SET NOCOUNT ON; 

        -- Insert statements for procedure here 
        SELECT  TOP 1000 

        LOG_ID --somehow store this and execute the dbo.getLogByLogId procedure here 

        FROM dbo.LOG_TAG a 
        WHERE a.TAG = @TAG 

        -- Execute dbo.getLogByLogId stored procedure
    DECLARE @logId INTEGER
    SET @logId = <some value>
    EXEC dbo.getLogByLogId @logId
END

Однако трудная часть вашего вопроса заключается в том, что ваша процедура dbo.getLogByLogId может принимать только один параметр LogID и, следовательно, сможет возвращать только одну запись журнала. Вам необходимо вернуть информацию для всех журналов, в которых для LogId имеется соответствующая запись в таблице тегов.

Правильный способ сделать это - присоединиться к таблицам Log и Tag вместе, вот так:

SELECT *
FROM dbo.LOG_TAG a
INNER JOIN dbo.LOG b ON a.LOG_ID = b.LOG_ID
WHERE a.TAG = @TAG

Если вы хотите вернуть один и тот же logId несколько раз, вы можете использовать ключевое слово DISTINCT в операторе SELECT, чтобы отфильтровать дублированные logIds.

Вы также можете переписать вашу процедуру dbo.getLogByLogId как пользовательскую функцию (UDF). Пользовательские функции могут принимать таблицу в качестве параметра и возвращать результат таблицы.

Введение в пользовательские функции можно найти в этой статье .

0 голосов
/ 12 января 2010

Если вы хотите вызвать другого спрока из него, просто наберите:

CREATE PROCEDURE myTestProc
AS
BEGIN

--Do some work in this procedure
SELECT blah FROM foo

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