【问题标题】:When I try to execute a stored proc ,from another stored proc, from the middle-tier -- nothing happens当我尝试从中间层执行存储过程时,从另一个存储过程中 - 没有任何反应
【发布时间】:2010-02-01 20:27:41
【问题描述】:

我们有能力从中间层执行存储过程。基本上,在名为“SQLJobStep”的数据库表中,我们有一个名为“StoredProcedure”的 varchar(300) 列,其中包含如下内容:

usp_SendReminderEmails @Debug=0, @LoginID

通过中间层,用户点击一个链接来运行他们选择的过程。在后端发生的是一个 proc ("usp_SQLJobsActionGet") 从 "SQLJobStep.StoredProcedure" 列中查找正确的值并执行上面的值。

这是“usp_SQLJobsActionGet”中执行上述值的部分代码:

DECLARE @StepId int
DECLARE @LoginID varchar(12)
DECLARE @StoredProcedure varchar(300)

SET @StepId = 74
SET @LoginID = 'Yoav'

SELECT @StoredProcedure = SJS.StoredProcedure 
FROM SQLJobStep AS SJS
WHERE SJS.StepId = @StepId

SET @StoredProcedure = ISNULL(@StoredProcedure, '')

IF CHARINDEX('@LoginID', @StoredProcedure) > 0
BEGIN
    SET @LoginID = ISNULL(@LoginID, 'UNKNOWN')
    SET @StoredProcedure = REPLACE(@StoredProcedure, '@LoginID', '@LoginID = ''' + @LoginID + '''')
END

IF @StoredProcedure != ''
BEGIN
    EXEC(@StoredProcedure)
END    

相当简单的东西......

以上代码将原始值转换为(然后执行):

usp_SendReminderEmails @Debug=0, @LoginID = 'Yoav'

问题来了:

执行“usp_SendReminderEmails @Debug=0, @LoginID = 'Yoav'” 值时没有任何反应。没有错误返回到中间层。但我知道从 SQLJobStep 表中提取了一个值,因为我们还有其他存储过程值被提取并且它们运行良好。 (请注意,其他值只有@LoginID 参数,而这也有@Debug=0。)

同时,如果我在 SQL Management Studio 中运行上面的代码(包括内脏代码和直接调用“usp_SQLJobsActionGet”),它可以完美运行。

你有什么建议吗?我确定我遗漏了一些非常基本的东西。

谢谢。

【问题讨论】:

  • 您是否尝试过使用 sql profiler 来查看单击链接后究竟执行了什么 sql?
  • 尝试添加一个PRINT @StoredProcedure(或将其写入数据库日志表等),看看有什么...
  • 您是否在相同的用户上下文中执行代码?您是否使用与中间层使用的凭据相同的凭据在 SQL mgmt studio 中进行连接?

标签: c# sql-server-2005 stored-procedures


【解决方案1】:

我的建议?使用 sp_ExecuteSQL 而不是串联/替换:

IF @StoredProcedure != ''
BEGIN
    EXEC sp_ExecuteSQL @StoredProcedure, N'@LoginID varchar(12)', @LoginID
END

不过,总的来说 - EXEC 应该可以工作;你确定@StoredProcedure 不为空吗?

【讨论】:

  • 嗨,Marc:不幸的是,使用 sp_ExecuteSQL 没有任何区别。确实@StoredProcedure 具有价值。事实上,我将预期值硬编码到了 usp_SQLJobsActionGet 过程中。和以前一样,通过 Management Studio 可以工作,但通过前端却不行。
  • @Yoav - 它是如何输出数据的?是否使用SELECT?还是使用PRINT? (第一个=好,第二个=坏)
【解决方案2】:

感谢您的帮助。我找到了我的问题的答案,你可以猜到它与我最初描述的问题之外的问题有关:

在 usp_SendReminderEmails proc 中,我们调用另一个 proc 来审核每个发送的电子邮件记录。此审计过程将记录插入审计表,然后返回标识 (SELECT TOP 1 SCOPE_IDENTITY())。虽然它一次只返回 1 条记录,但它恰好在游标中调用(在 usp_SendReminderEmails 中)以一次发送每封电子邮件(注意:这是一个 SQL 作业过程)。

我注意到,在 Management Studio 中执行 usp_SendReminderEmails @Debug=0, @LoginID = 'Yoav' 后,它工作正常,但返回警告(!):

查询已超出结果网格中可显示的最大结果集数。网格中仅显示前 100 个结果集。

因此,当从中间层调用 proc 时,什么都没有发生 - 没有返回错误,但也没有处理 usp_SendReminderEmails。我通过在 usp_SendReminderEmails 中的临时表的插入中调用审计过程来修复它,从而确保它不会被返回(因为它只是一个标识值):

INSERT INTO #AuditData (AuditDataId)
EXEC usp_AuditSave

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-15
    • 2018-04-18
    • 1970-01-01
    • 2014-09-17
    • 2020-12-10
    相关资源
    最近更新 更多