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

MSSQL
SQL Server中容易混淆的数据类型
影响SQL Server性能的主要原因
浅谈SQL Server查询优化器中的JOIN算法
怎样缩小SQL Server数据库日志文件
SQL Server 2005最值得你升级的10个理由
SQL Server 商务智能特性对比
SQL Server 2005 SP1的新特性
怎样使用SQL Server来过滤数据
在SQL Server中处理空值时涉及的三个问题
怎样才能保护好 SQL Server 数据库
SQL SERVER数据库口令的脆弱性
SQL Server中的动态和静态内存分配
SQL存储过程学习:特殊的存储过程-触发器
几条常见的数据库分页 SQL 语句
SQL Server 2008服务器合并功能介绍
SQL Server数据库开发的二十一条军规
SQL Server 2008 的管理能力
快速删除重复记录,SQL Server如何实现?
将MySQL数据导入到Sql Server中
SQL Server和MySQL的安全性分析

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 141 ::
收藏到网摘: 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
-------------------------------------------------------------------------
生成的脚本就为:<