使用SELECT执行存储过程

时间:2015-01-27 12:05:22

标签: sql-server select insert execute

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

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

我目前拥有的是一个返回正确值的select语句,但我不确定现在如何将这些值传递给存储过程。我希望我可以直接在存储过程执行命令中使用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

谢谢,加文

4 个答案:

答案 0 :(得分:0)

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

EXECUTE servername.dbname.owner.procedure_name

如果同一服务器上的两个数据库都使用以下

调用您的过程
EXECUTE dbname.owner.procedure_name

答案 1 :(得分:0)

您可以使用光标:

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

答案 2 :(得分:0)

您可以使用以下内容:

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

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

答案 3 :(得分:0)

要回答您的问题,如果必须循环显示结果,那么您可以使用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

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

我应该指出(虽然你已经说过你不能修改程序,其他人也可以阅读这个问题),实际将结果传递给存储过程的最佳方法是使用表格 - 重要参数。第一步是创建您的类型:

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,因为您提到了审核表,它通常是访问已插入数据的最佳方式。

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

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;