2010-01-12 8 views
1

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

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

У меня есть хранимая процедура, которая выглядит примерно так, чтобы выбрать журнал 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 

Благодарности

ответ

2

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

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

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

0

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

CREATE PROCEDURE myTestProc 
AS 
BEGIN 

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

--now call another sproc 
EXEC nameOfSecondSproc 
END 
0

Единственный путь вы можете achive то, что вы пытаетесь это с помощью 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 цикле, то вы можете выполнить зр вы хотите и вставить значение от в таблицу переменных ,

INSERT INTO @Table EXEC sp_MySP @ID 
0

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

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 имеет соответствующую запись в таблице тегов.

правильный способ сделать это было бы соединить таблицы записи и пометки вместе, вот так:

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). UDF могут принимать таблицу в качестве параметра и возвращать результат таблицы.

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

Смежные вопросы