使用 SELECT 执行存储过程

execute stored procedure using SELECT

我正在尝试从一个数据库中的 table 中提取数据以插入另一个数据库中的 table。

插入有一个预先编写的存储过程,它带有多个参数,我必须使用它,因为它还会更新审计 tables。

我目前拥有的是 select 语句,其中 returns 是正确的值,但我不确定现在如何将这些值传递给存储过程。我希望我可以直接在存储过程执行命令中使用 select 语句,但似乎这是不可能的。

谁能建议我如何最好地实现上述目标?

编辑 - 我当前的 SQL 是:

DECLARE @client INT, @Fee_Earner INT, @RecordType NVARCHAR(10), @RecordDate DATETIME, @Abstract NVARCHAR(500), @Comments NVARCHAR(500)

SELECT
@client = HC.CLIENT_UNO,
@Fee_Earner = HP.EMPL_UNO,
@RecordType = 'WILL ',
@RecordDate = W.WILLDATE1,
@Abstract = W.OTHERDOC1 + ' '  + W.OTHERDOC2 + ' ' + W.OTHERDOC3,
@Comments = W.NOTES
FROM
devpmsql.cmsnet_dev.dbo.HBM_CLIENT HC
RIGHT OUTER JOIN <DBNAME>.WILLS W ON W.AN COLLATE DATABASE_DEFAULT = HC.CLIENT_CODE COLLATE DATABASE_DEFAULT
LEFT OUTER JOIN <DBNAME>.HBM_PERSNL HP ON HP.EMPLOYEE_CODE COLLATE DATABASE_DEFAULT = W.PARTNER COLLATE DATABASE_DEFAULT

PRINT @client
PRINT @Fee_Earner
PRINT @RecordType
PRINT @RecordDate
PRINT @Abstract
PRINT @Comments

谢谢,加文

如果您想在远程服务器上执行过程,那么您可以create linked server然后使用以下语法调用您的过程

EXECUTE servername.dbname.owner.procedure_name

如果两个数据库都在同一台服务器上,那么您可以使用以下方式调用您的过程

EXECUTE dbname.owner.procedure_name

您可以使用游标:

DECLARE @client INT, @Fee_Earner INT, @RecordType NVARCHAR(10), @RecordDate DATETIME, @Abstract NVARCHAR(500), @Comments NVARCHAR(500)


declare aCursor cursor for 
SELECT
HC.CLIENT_UNO,
HP.EMPL_UNO,
'WILL ',
W.WILLDATE1,
W.OTHERDOC1 + ' '  + W.OTHERDOC2 + ' ' + W.OTHERDOC3,
W.NOTES
FROM
devpmsql.cmsnet_dev.dbo.HBM_CLIENT HC
RIGHT OUTER JOIN <DBNAME>.WILLS W ON W.AN COLLATE DATABASE_DEFAULT = HC.CLIENT_CODE COLLATE DATABASE_DEFAULT
LEFT OUTER JOIN <DBNAME>.HBM_PERSNL HP ON HP.EMPLOYEE_CODE COLLATE DATABASE_DEFAULT = W.PARTNER COLLATE DATABASE_DEFAULT

open aCursor
fetch NEXT from aCursor into 
@client,
@Fee_Earner,
@RecordType,
@RecordDate,
@Abstract,
@Comments

while @@FETCH_STATUS = 0
begin

    exec yourSP @client,
        @Fee_Earner,
        @RecordType,
        @RecordDate,
        @Abstract,
        @Comments

    fetch NEXT from aCursor into 
    @client,
    @Fee_Earner,
    @RecordType,
    @RecordDate,
    @Abstract,
    @Comments

end

您可以使用以下内容:

SELECT  * FROM OPENROWSET ('SQLOLEDB','Server=(local);TRUSTED_CONNECTION=YES;','set fmtonly off exec master.dbo.sp_who')

master.dbo.sp_who 替换为您的存储过程。

要回答您的问题,如果您必须 遍历结果,那么您可以使用 cursor:

DECLARE @client INT, 
        @Fee_Earner INT, 
        @RecordType NVARCHAR(10) = 'WILL', 
        @RecordDate DATETIME, 
        @Abstract NVARCHAR(500), 
        @Comments NVARCHAR(500);


DECLARE ClientCursor CURSOR LOCAL STATIC FAST_FORWARD
FOR
SELECT  HC.CLIENT_UNO, 
        HP.EMPL_UNO, 
        W.WILLDATE1,
        Abstract = W.OTHERDOC1 + ' '  + W.OTHERDOC2 + ' ' + W.OTHERDOC3,
        W.NOTES
FROM    devpmsql.cmsnet_dev.dbo.HBM_CLIENT HC
        RIGHT OUTER JOIN <DBNAME>.WILLS W 
            ON W.AN COLLATE DATABASE_DEFAULT = HC.CLIENT_CODE COLLATE DATABASE_DEFAULT
        LEFT OUTER JOIN <DBNAME>.HBM_PERSNL HP 
            ON HP.EMPLOYEE_CODE COLLATE DATABASE_DEFAULT = W.PARTNER COLLATE DATABASE_DEFAULT


OPEN ClientCursor;
FETCH NEXT FROM ClientCursor INTO @client, @Fee_Earner, @RecordDate, @Abstract, @Comments;

WHILE @@FETCH_STATUS = 0
BEGIN
    EXECUTE dbo.YourStoredProcedure @client, @Fee_Earner, @RecordType @RecordDate, @Abstract, @Comments;

    FETCH NEXT FROM ClientCursor INTO @client, @Fee_Earner, @RecordDate, @Abstract, @Comments;

END

我必须强调正确声明光标的重要性。通常最好避免使用游标,如果有基于集合的方法,那么应该采用它,但是游标的名声更差,因为使用不当。如果,如上所述,你只想在本地读取访问你的记录,只读取它们并且只在游标中向前移动,那么告诉它,那样内存不会分配给执行你无意执行的任务。

我应该指出(虽然你说过你不能修改这个过程,但阅读这个问题的其他人可能能够)实际将结果传递给存储过程的最好方法是使用 table-值参数。第一步是创建您的类型:

CREATE TYPE dbo.YourTypeName AS TABLE
(
    client INT, 
    Fee_Earner INT, 
    RecordType NVARCHAR(10), 
    RecordDate DATETIME, 
    Abstract NVARCHAR(500), 
    Comments NVARCHAR(500)
);

那么你的程序应该是这样的:

CREATE PROCEDURE dbo.InsertValues @NewValues dbo.YourTypeName READONLY
AS
BEGIN
    INSERT dbo.YourTable (Client, Fee_Earner, RecordType, RecordDate, Abstract, Comments)
    OUTPUT inserted.Client, #'Created', GETDATE() INTO dbo.YourAuditTable (Client, EventName, CreatedDate)
    SELECT Client, Fee_Earner, RecordType, RecordDate, Abstract, Comments
    FROM NewValues;

END

我已经包括了 `OUTPUT' Clause 因为你提到了审计 tables,它通常是访问已插入数据的最佳方式。

最后,调用你的过程你会使用类似的东西:

DECLARE @T dbo.YourTypeName;
INSERT @T (Client, Fee_Earner, RecordType, RecordDate, Abstract, Comments)
SELECT  HC.CLIENT_UNO, 
        HP.EMPL_UNO, 
        RecordType = 'WILL',
        W.WILLDATE1,
        Abstract = W.OTHERDOC1 + ' '  + W.OTHERDOC2 + ' ' + W.OTHERDOC3,
        W.NOTES
FROM    devpmsql.cmsnet_dev.dbo.HBM_CLIENT HC
        RIGHT OUTER JOIN <DBNAME>.WILLS W 
            ON W.AN COLLATE DATABASE_DEFAULT = HC.CLIENT_CODE COLLATE DATABASE_DEFAULT
        LEFT OUTER JOIN <DBNAME>.HBM_PERSNL HP 
            ON HP.EMPLOYEE_CODE COLLATE DATABASE_DEFAULT = W.PARTNER COLLATE DATABASE_DEFAULT;


EXECUTE dbo.InsertValues @T;