当前位置: 首页 > 图文教程 > 数据库 > MSSQL > SQL脚本生成的一些BUG

MSSQL
SQL Server SA权限总结经典技术
ASP数据库编程SQL常用技巧
SQL SERVER数据库开发之存储过程应用
SQL Server 2000的安全配置
MSSQL经典语句
SQL 经典语句
有用的SQL语句(删除重复记录,收缩日志)
Access 数据类型与 MS SQL 数据类型的相应
SQL语句示例
SQL数据类型详解
将Sql Server对象的当前拥有者更改成目标拥有者
MSSQL内外连接(INNER JOIN)语句详解
SQL 外链接操作小结 inner join left join right join
SQL Server中网络备份一例
SQL语句导入导出大全
SQL 新增/修改 表字段列的类型等
系统存储过程,sp_executesql
sql2005开启xp_cmdshell
实例学习SQL的Select命令
删除数据库中重复数据的几个方法

MSSQL 中的 SQL脚本生成的一些BUG


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 56 ::
收藏到网摘: n/a

微软的SQL脚本生成令我伤透了心……我一直以为是我的程序上的问题,或者我操作上的失误,
并且,客服务人员屡屡埋怨我的程序bug,多次测试之后,靠,原来都是微软惹的祸……

Sql Server 的脚本生成有不少漏洞,经常由它生成的脚本运行起来却有错误。下面举例说明:

1、并没有根据sysdenpends的依赖关系生成SQL代码,而是根据“优先级”(呵呵,所谓的优先级)来生成。
比如:他认为view的优先级就要比function高。
那么,我写了下面的测试程序,形成如下的依赖关系:fnT1  <--  vwT1  <--  fnT2
就是,view vwT1处于依赖的中间。
------------------------------------
Create function fnT1()
  Returns Integer
As
begin
  Return 123
end
go

Create view vwT1
As
  Select aa=dbo.fnT1()

Go

Create function fnT2()
  Returns Table
As
  Return (Select * From vwT1)
Go
-------------------------------------
运行到数据库之后,用Enterprise生成SQL代码。(选项不一样,会有所不同,我没有选数据库和用户的)
-----------------------------------------------------------------------------------
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[fnT1]') and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[fnT1]
GO

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[fnT2]') and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[fnT2]
GO

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[vwT1]') and OBJECTPROPERTY(id, N'IsView') = 1)
drop view [dbo].[vwT1]
GO

SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO

Create view vwT1
As
  Select aa=dbo.fnT1()

GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO

Create function fnT1()
  Returns Integer
As
begin
  Return 123
end

GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO

Create function fnT2()
  Returns Table
As
  Return (Select * From vwT1)

GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
-----------------------------------------------------------------------------
呵呵,一眼你就可以看出来了,建立view要比建立function先。而不是根据依赖关系建立……
毫无疑问,将会得到如下的错误:(这个错误可真严重!害得我好惨……)
---------------------------------------------------
服务器: 消息 208,级别 16,状态 1,过程 vwT1,行 4
对象名 'dbo.fnT1' 无效。
服务器: 消息 208,级别 16,状态 1,过程 fnT2,行 5
对象名 'vwT1' 无效。
---------------------------------------------------
2、作业脚本。

这个我就不说了,bug还不是很严重,主要是中文“--”注释符的问题,英文版我没有测试过,不过猜想应当没有这个bug。
大家可以试试看。

3、还有一个SP的问题。

大家看过我的精华里面有spGetIDStr和spAnalyseStrList了吧,关系是后者依赖于前者。可是spGetIDStr我并没有调用任何的表。
因此,每当运行Sql Server生成的脚本的时候,总是报告(大概是这样的信息):
------------------------------------------------------------------------
   spGetIDStr并不存在,无法在sysdepends里建立依赖关系,存储过程spAnalyseStrList仍然建立。
--------------------------------------------------------------------------
无论我手工修改他的建立顺序还是什么的,用它生成的脚本就是有错。呵呵,这个破微软!
这里,再看看第三个bug,看我下面的测试程序:
(原理:当sp没有对表或视图等数据库对象有依赖关系的时候,sp被别的sp引用的时候也将无法建立依赖关系)
形成依赖关系:spB1 <---  spA1
------------------------------------------------------------------------
Create Proc spB1
As
  Return 11

Go

Create proc spA1
As
Begin
  Declare @i int
  Exec @i=spB1
  Return @i*2
End
Go
-------------------------------------------------------------------------
生成的脚本就为:<