SQL Server运行旧版本的存储过程

时间:2014-03-28 19:14:02

标签: sql-server vb.net sql-server-2008 tsql

我们有一个用户,当他们从VB应用程序运行存储过程时,它运行旧版本的SP。旧版本,我的意思是被存储过程更新覆盖的版本。

  • 我们只有1个架构(dbo)
  • 我在服务器上的任何其他数据库(包括主数据库)中检查了相同的SP,它只存在一次
  • 我们使用NT Auth
  • 我使用SQL事件探查器来确保正在调用正确的SP并且它是。
  • 我甚至通过在BEGIN之后对第一行的sp进行以下更改来测试这个:

    raiserror('这是更新的SP,错误!',16,1)

    返回

此用户不会收到此错误,而是会收到原始错误。他们得到的错误并不重要,因为它已被修复,但就像这个用户正在调用另一个SP。

为了让事情更加混乱,我们在几个月前使用不同的数据库和vb应用程序以及2个不同的用户遇到了同样的问题。我们为修复问题所做的是将它们从活动导演中删除,然后使用其他名称添加它们。

有没有人知道可能会发生什么,还有什么我可以尝试而不是重新创建用户,或者有没有其他人遇到过这个?请告诉我,我不是疯了。

编辑:我们在VB应用程序和SQL Server中更改了SP的名称并观察了SQL事件探查器,它确实运行了重命名的SP,但它仍然运行了旧的代码SP。所有代码都被删除了,唯一存在的就是Raiserror ......必须有一些我们缺少的东西。

EDIT2 :似乎添加到SP的可选BIT参数与此有关。这是几个月前SP在改变之前的样子:

ALTER PROCEDURE [dbo].[BulkLoadSomeData]
    @UserName varchar(50),
    @FileName as varchar(max),
    @OriginalFileName as varchar(max)
AS
BEGIN
  SET NOCOUNT ON;
  BULK INSERT ....
  ...Process the data...
END

现在:

ALTER PROCEDURE [dbo].[BulkLoadSomeData]
  @UserName varchar(50),
  @FileName as varchar(max),
  @OriginalFileName as varchar(max),
  @HasElevatedSecurity bit = 0
AS
BEGIN
  SET NOCOUNT ON;
  IF @HasElevatedSecurity = 0 BEGIN
    ...Stick this into a process queue to run with higher priviledges...
    ...code ommited...
    RETURN --Must return so we dont run the rest of the code
  END  
  BULK INSERT ....    
  ...Process the data...
END

所以我们添加了" raiserror('这是更新的SP,错误!',16,1)"在" SET NOCOUNT ON之后的行上;"并且用户仍然收到有关无法访问BULK INSERT的错误,但其他人都收到了我们提出的错误。

然后我创建了一个包含这四个paramanters的表,并用一些插入SQL替换了RAISERROR。一个用户获取BULK INSERT错误并且表中没有记录,其他人都插入记录并运行该过程而没有错误。在SQL事件探查器中,所有exec语句都是相同的。

BTW,SQL Profiler显示了这个:

exec BulkLoadSomeData @UserName='User1', @FileName='UNC Path and file name with no special characters', @OriginalFileName='Line the other file name'

4 个答案:

答案 0 :(得分:1)

您必须重新启动SQL Server数据库引擎服务。 看看这个SO问题: Debugging does not show current stored procedure version

答案 1 :(得分:1)

根据存储过程代码和我们在 EDIT2 下看到的其他信息,我们知道:

  1. 正在调用BULK INSERT
  2. "用户仍然收到有关无法访问BULK INSERT的错误,但其他人都收到了我们提出的错误"
  3. 某些T-SQL函数(例如OPENQUERY,OPENROWSET,BULK INSERT等)会对安全性进行预验证。用户必须具有INSERT和ADMINISTER BULK OPERATIONS权限,在某些情况下还必须具有ALTER TABLE,以便执行BULK INSERT。此外,用户的NTFS / Active Directory权限(如果使用Windows身份验证)或"登录为"将验证SQL Server服务帐户(如果使用SQL Server身份验证)以确保该文件可读。

    在调用存储过程(或函数等)而不是执行每一行时,会发生预验证(或至少我调用的内容"预验证")。如果此时发生错误,则Proc中的所有代码都不会执行,包括RAISERROR或INSERT到日志表中。

    因此,您看到的行为的最可能原因是具有该问题的用户缺少a)一个或多个所需的SQL Server权限,或b)相应的NTFS权限,或c)所有这些。

    鉴于错误是关于无法访问BULK INSERT,我的猜测是这个特定用户缺少一个或多个SQL Server权限。

答案 2 :(得分:0)

您是否尝试删除proc然后重新添加它(而不是alter proc)?

您是否尝试过使用sp_recompile?

您是否尝试过使用"重新编译"存储过程中的选项?

你有没有尝试牺牲处女?

答案 3 :(得分:0)

当您运行SQL事件探查器时,您是否看到重命名的proc由似乎正在运行旧代码的用户调用?这意味着,您确定您在Profiler中看到的事件是该特定用户吗?您声明更改Active Directory帐户是过去唯一适用于该案例的帐户,这意味着这与他们的SID和/或登录有关。他们是通过相同名称的登录还是通过角色登录到SQL Server?

如果通过登录名称登录(例如不是角色),则将其登录属性与其他有效的登录进行比较。检查以下内容:默认数据库,默认架构,服务器角色,数据库角色。

你说你删除并重新创建了proc但是他们仍然运行着#34; old"码。如何删除proc并让他们尝试执行它。如果他们仍然可以在它不存在的情况下运行它,那么检查如下:

  • 他们是否真的连接到您认为的相同服务器(远射但不能仅根据此处显示的信息排除)。
  • 他们是否连接到您认为他们正在连接的数据库?
  • 是否涉及可以重新映射proc的SYNONYMS? (SELECT * FROM sys.synonyms
  • 是否涉及任何编号程序(远射但它们不会出现在granadaCoder提供的INFORMATION_SCHEMA查询中)(SELECT * FROM sys.numbered_procedures