使用 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;
我正在尝试从一个数据库中的 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;