繁体   English   中英

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

[英]Invalid object name error when trying to execute stored procedure?

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

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

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

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

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

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

sql profiler显示什么?

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

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

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

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

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

sqlcmd.CommandText = "dbo.SetMapping";

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

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

原因是它可能在您在同一页面上运行的完全独立的损坏存储过程中引用SQL错误。 例如,假设您有一个存储过程来获取表的内容; with the (rather than the table the stored procedure was referencing) in another stored procedure on the same page then this error will be thrown. 如果您错误地将 (而不是存储过程所引用的表)的表连接在同一页面上的另一个存储过程中,则会抛出此错误。 这可能会令人困惑,因为您知道引用的存储过程工作得很好!

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

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

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

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

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

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

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

希望有所帮助。

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

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

你绝对确定你输入的名字是否正确?

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM