【问题标题】:Invalid object name error when trying to execute stored procedure?尝试执行存储过程时出现无效的对象名称错误?
【发布时间】:2010-10-26 12:58:34
【问题描述】:

不确定是什么问题我有一个存储过程,它的名称与我所调用的完全一致,但它总是给我这个无效对象错误。这是连接代码,错误在倒数第二行抛出。

SqlConnection cnstr = new SqlConnection(ConfigurationManager.ConnectionStrings["darconn"].ConnectionString);
SqlCommand sqlcmd = new SqlCommand();

sqlcmd.CommandType = CommandType.StoredProcedure;
sqlcmd.Connection = cnstr;
sqlcmd.CommandText = "SetMapping";

String[] pullKodID = bundlelist.SelectedValue.ToString().Split(':');
int kod_id = System.Convert.ToInt32(pullKodID[0]);

sqlcmd.Parameters.Add("@kod_id", kod_id);
sqlcmd.Parameters.Add("@ell_id", courselist.Items[i].Text);
cnstr.Open();
sqlcmd.ExecuteNonQuery();
cnstr.Close();

【问题讨论】:

标签: asp.net sql-server stored-procedures


【解决方案1】:

存储过程很可能对您的代码不可见,因为它是由除dbo 或连接字符串中指定的用户以外的用户创建/拥有的。

您是否尝试过在存储过程名称前加上 dbo 前缀?例如“dbo.SetMapping”。

如果失败,请使用 Management Studio/Enterprise Manager 找出谁拥有存储过程,然后将其重新创建为 dbo 或更新您的代码/连接字符串以使用适当的用户。

【讨论】:

  • 试过dbo,没有运气,添加了用户来授予程序执行,仍然没有运气,我之前已经多次访问过这样的存储过程,这真的很奇怪......
【解决方案2】:

我遇到了同样的问题,结果是我在 [master] 数据库中创建了存储过程,而不是我应该处理的那个。可能不是您的问题,但需要注意。

【讨论】:

    【解决方案3】:

    sql profiler 显示什么?

    您可以在应用程序的上下文之外执行吗?来自 mgt studio 或 qry 分析仪?

    【讨论】:

    • 这也是我的建议。您可以在查询分析器中执行 sp 吗?此外,通常在“无效对象”错误中,它会告诉您无效对象是什么。它是告诉你 SP 的名称还是 SP 内部引用的对象的名称?
    【解决方案4】:

    检查存储过程中表名的拼写。

    保存存储过程时,它会检查所用表中的字段名称,但可以保存使用不存在(或拼写错误)的表名的存储过程。

    【讨论】:

      【解决方案5】:

      检查存储过程以查看它是否归“dbo”所有,因此名称将是“dbo.SetMapping”而不是“SomeUser.SetMapping”之类的名称

      我还会明确指定“dbo”。以名义

      sqlcmd.CommandText = "dbo.SetMapping";
      

      【讨论】:

        【解决方案6】:

        你确定你输入的名字正确吗?

        【讨论】:

          【解决方案7】:

          这是一个长镜头,但已经列出了常见的答案。

          很少有脚本可以在目录中获得与脚本中不同的名称。我相信这可能会导致类似于您所看到的问题。

          以下脚本将检查您的数据库以查看目录中是否有与脚本不匹配的项目。 (您需要 SQL 2005 或更高版本才能使用此功能)

          -------------------------------------------------------------------------
          -- Check Syntax of Database Objects
          -- Copyrighted (2009).  Free to use as a tool to check your own code or in 
          --  any software not sold. All other uses require written permission from Author
          -- Author: Stephen Schaff
          -------------------------------------------------------------------------
          -- Turn on ParseOnly so that we don't actually execute anything.
          SET PARSEONLY ON 
          GO
          
          -- Create a table to iterate through
          declare @ObjectList table (ID_NUM int NOT NULL IDENTITY (1, 1), OBJ_NAME varchar(255), OBJ_TYPE char(2))
          
          -- Get a list of most of the scriptable objects in the DB.
          insert into @ObjectList (OBJ_NAME, OBJ_TYPE)
          SELECT   name, type
          FROM     sysobjects WHERE type in ('P', 'FN', 'IF', 'TF', 'TR', 'V')
          order by type, name
          
          -- Var to hold the SQL that we will be syntax checking
          declare @SQLToCheckSyntaxFor varchar(max)
          -- Var to hold the name of the object we are currently checking
          declare @ObjectName varchar(255)
          -- Var to hold the type of the object we are currently checking
          declare @ObjectType char(2)
          -- Var to indicate our current location in iterating through the list of objects
          declare @IDNum int
          -- Var to indicate the max number of objects we need to iterate through
          declare @MaxIDNum int
          -- Set the inital value and max value
          select  @IDNum = Min(ID_NUM), @MaxIDNum = Max(ID_NUM)
          from    @ObjectList
          
          -- Begin iteration
          while @IDNum <= @MaxIDNum
          begin
            -- Load per iteration values here
            select  @ObjectName = OBJ_NAME, @ObjectType = OBJ_TYPE
            from    @ObjectList
            where   ID_NUM = @IDNum 
          
            -- Get the text of the db Object (ie create script for the sproc)
            SELECT @SQLToCheckSyntaxFor = OBJECT_DEFINITION(OBJECT_ID(@ObjectName, @ObjectType))
          
            begin try
              -- Run the create script (remember that PARSEONLY has been turned on)
              EXECUTE(@SQLToCheckSyntaxFor)
            end try
            begin catch
              -- See if the object name is the same in the script and the catalog (kind of a special error)
              if (ERROR_PROCEDURE() <> @ObjectName)
              begin
                print 'Error in ' + @ObjectName
                print '  The Name in the script is ' + ERROR_PROCEDURE()+ '. (They don''t match)'
              end
          
            end catch
          
            -- Setup to iterate to the next item in the table
            select  @IDNum = case
                      when Min(ID_NUM) is NULL then @IDNum + 1
                      else Min(ID_NUM)
                    end  
            from    @ObjectList
            where   ID_NUM > @IDNum
          
          end
          -- Turn the ParseOnly back off.
          SET PARSEONLY OFF 
          GO
          

          (附带说明,如果您想查看数据库中的所有错误,请将其添加到 if (ERROR_PROCEDURE() &lt;&gt; @ObjectName) 块之后。)

          else if (ERROR_MESSAGE() <> 'There is already an object named ''' + ERROR_PROCEDURE() + ''' in the database.')
          begin
            -- Report the error that we got.
            print 'Error in ' + ERROR_PROCEDURE()
            print '  ERROR TEXT: ' + ERROR_MESSAGE() 
          end
          

          【讨论】:

          • 在 SQLServerCentral 上找到了那个脚本,它是垃圾。我们正在从 2000(兼容模式)迁移到 2008,我们发现一些存储过程在 ORDER BY 语句中具有无效的列名,还有一些从不存在的表中选择数据。 2000 引擎不在乎,它只是忽略它。无论语法错误如何,2008 仍将创建该过程,但在实际执行它们时会崩溃。此语法检查过程找不到它们。有人有其他选择吗?
          • @Cory Larson 试试我的工具 checktsql 或使用我博客上的代码devio.wordpress.com/2010/05/28/checking-ms-sql-server-objects
          【解决方案8】:

          数据库是否使用区分大小写的排序规则?如果是这样,您的 C# 代码中的情况是否与数据库中的情况相同?

          【讨论】:

            【解决方案9】:

            它抱怨的实际对象的名称是什么?我在存储过程中看到了同样的问题,实际上存储过程本身没有问题 - 但由于拼写错误,存储过程中使用的表的名称是错误的(存储过程名称被意外粘贴为表名),因此它返回了与 sproc 名称匹配的 Invalid Object name 错误 - 这非常令人困惑。

            尝试更改存储过程名称并从您的代码中再次调用它,看看会发生什么 - 或尝试直接在 SQL Management Studio 中运行存储过程。

            如果这不起作用,那么就非常有条理,分而治之 - 回到基础,再次端到端检查所有内容。连接字符串是否正确,它在运行时连接到什么数据库,什么用户 id,sproc 在 Sql management studio 中是否独立工作等

            希望对您有所帮助。

            【讨论】:

              【解决方案10】:

              不管怎样,我在 .NET 4 上遇到了一个完全不同的问题,它产生了相同的异常,但几乎没有有用的信息来诊断它。

              我更新了我的 DBML 中的几个表。我可能已经重新加载了一个存储过程,但我不记得这样做了。

              designer.cs 中留下了以下 sproc 包装器:

              [global::System.Data.Linq.Mapping.FunctionAttribute(Name="dbo.GetSomeInformation", IsComposable=true)]
              public IQueryable<GetSomeInformationResult> GetSomeInformation([global::System.Data.Linq.Mapping.ParameterAttribute(DbType="BigInt")] System.Nullable<long> infoId)
              {
                  return this.CreateMethodCallQuery<GetSomeInformationResult>(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), infoId);
              }
              

              CreateMethodCallQuery 用于调用表值函数,而不是存储过程。我很困惑为什么它会改变这一点。我将其还原为使用ExecuteMethodCall

              [global::System.Data.Linq.Mapping.FunctionAttribute(Name="dbo.GetSomeInformation")]
              public ISingleResult<GetSomeInformationResult> GetSomeInformation([global::System.Data.Linq.Mapping.ParameterAttribute(DbType="BigInt")] System.Nullable<long> infoId)
              {
                  IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), infoId);
                  return ((ISingleResult<GetSomeInformationResult>)(result.ReturnValue));
              }
              

              一切都很好。很奇怪。

              更新:这似乎是由于 Visual Studio 在将存储过程添加到 dbml 时决定它是一个表值函数造成的。我以前从未见过这种情况。

              “IsComposable”标志似乎是它区分存储过程和表值函数的唯一方法。一旦我从 dbml 中的 Function 节点清除了标志,Visual Studio 就会在设计器文件中生成正确的代码。

              【讨论】:

                【解决方案11】:

                首先确保您的存储过程确实在 .net 之外工作。如果它工作得很好,那么请考虑以下...

                如果引用的对象正常工作,此错误可能会产生误导,请检查您在同一页面上使用的其他存储过程是否存在对“对象”的无效引用

                原因是它可能引用了您在同一页面上运行的完全独立损坏的存储过程中的 SQL 错误。例如,假设您有一个存储过程来获取表的内容;如果您在同一页面上的另一个存储过程中错误地将 存储过程(而不是存储过程引用的表)连接起来,则会引发此错误。这可能会令人困惑,因为您知道引用的存储过程可以正常工作!

                【讨论】:

                  【解决方案12】:

                  我在过程中输入了错误的表名,这就是我收到该错误的原因。

                  示例:过程中有一个名为test2 的表,其中包含表test 中的字段。它看起来像:

                  insert into test2 (fields from test) values...

                  【讨论】:

                    【解决方案13】:

                    我有类似的问题。 我忘了写到我的实际数据库的完整路径。 所以你必须写 select *From [your databasename].[dbo].[object name] 在我的例子中是实际命名数据库中的一个表对象 所以,select *from [practical].[dbo].[employee] 同样的逻辑也适用于存储过程

                    【讨论】:

                      【解决方案14】:

                      每次我尝试使用 ADO.Net 在 SQL 表中插入某些数据时,也会出现同样的错误。 后来,当我尝试直接在 SQL Server 中执行相同的命令时,我发现表上的触发器阻止了这种情况。所以也检查一下。

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 2023-03-15
                        • 2022-10-07
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2016-06-04
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多