尝试执行存储过程时无效的对象名称错误?

时间:2009-05-15 15:20:48

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

不确定是什么交易我的存储过程名称正是我所调用的,但它总是给我这个无效的对象错误。这是连接代码,错误是在那里的倒数第二行引发的。

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();

14 个答案:

答案 0 :(得分:5)

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

您是否尝试使用dbo为存储过程名称添加前缀?例如“dbo.SetMapping”。

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

答案 1 :(得分:2)

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

答案 2 :(得分:1)

sql profiler显示什么?

你可以在应用程序的上下文之外执行吗?来自mgt studio或qry analyzer?

答案 3 :(得分:1)

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

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

答案 4 :(得分:1)

检查存储过程以查看它是否属于'dbo',因此名称将为'dbo.SetMapping'而不是'SomeUser.SetMapping'

我还会明确指定'dbo'。在名称

sqlcmd.CommandText = "dbo.SetMapping";

答案 5 :(得分:0)

你绝对确定你输入了正确的名字吗?

答案 6 :(得分:0)

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

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

以下脚本将检查您的数据库,以查看目录中是否有与该脚本不匹配的项目。 (您需要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() <> @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

答案 7 :(得分:0)

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

答案 8 :(得分:0)

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

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

如果这不起作用那么就要非常有条理,分而治之 - 直接回到基础并再次检查端到端。连接字符串是否正确,它在运行时连接到什么数据库,什么用户ID,sproc在Sql管理工作室中自己运行等等

希望有所帮助。

答案 9 :(得分:0)

对于它的价值,我在.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就会在设计器文件中生成正确的代码。

答案 10 :(得分:0)

首先确保您的存储过程实际上在.net之外工作。如果工作正常,请考虑以下内容......

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

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

答案 11 :(得分:0)

我在程序中有错误的表名,这就是我收到错误的原因。

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

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

答案 12 :(得分:0)

我有类似的问题。 我忘记写完我的实际数据库的完整路径。 所以你必须编写select * From [你的数据库名]。[dbo]。[对象名] 在我的情况下是实际命名数据库中的表对象 所以,从[实用]中选择*。[dbo]。[员工] 同样的逻辑同样适用于存储过程

答案 13 :(得分:0)

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