日期:2014-05-18  浏览次数:20852 次

创建视图疑难问题,邹建同志请进!
有数据库D1和D2,D1中有表T1,D2中有表T2。由于特殊需要,要在D2中建一存储过程P1,P1的功能是先判断D1中如果有名为T1的表则删除,如果有名为T1的视图则删除;然后在数据库D1中建立一个名为T1的视图,T1的内容和数据库D2中的表T2相同。该存储过程如何写?

------解决方案--------------------
然后在数据库D1中建立一个名为T1的视图,T1的内容和数据库D2中的表T2相同
----------------------------------

这个视图的基础表是什么? 来自D2库吗? 如果这样, 似乎问题有多, 要求D1能正确访问D2, 而它们的身份验证很难解决, 除非你在这个处理外先解决好身份验证的问题.


至于判断对象是否存在及删除嘛, 倒是可以考虑利用openrowset, 判断是否存在通过查询D1的系统表(sysojects)就可以了, 是否存在和类型都可以判断出来

使用openrowset删除对象时, 要注意事务的问题, 需要设置(SET IMPLICIT_TRANSACTIONS OFF), 并且处理的语句中, 需要包含一个最简单的返回结果集的语句(openrowset要求有返回结果集)


------解决方案--------------------
兄弟,試圖的創建和刪除都是不可以跨數據庫操作的。所以如果你一定要這麼做的話,只能在數據庫D1中創建一個存儲過程專門用來刪除和創建試圖,然後在D2中傳建的存儲過程來調用D1中的這個存儲過程從而實現跨數據庫的試圖的刪除和傳建,代碼如下:
首先在D1中傳建一個存儲過程
create proc [dbo].[sp_DCview]
(
@type int,
----0:表示刪除試圖,其它值表示創建試圖
@viewname varchar(20)
----需要創建或者是刪除試圖的名稱
)
as
declare @SQL Nvarchar(800)
if(@type = 0)
---drop the view
begin
set @sql = N 'drop view '+@viewname
end
else
begin
set @sql = N 'create view '+@viewname+
N ' as '+
N 'select * from D2.dbo. '+@viewname;
end
exec sp_executesql @sql;
go


然後再在D2中傳建你所需要的存儲過程:
create proc [dbo].[sp_createt]
(@objectname varchar(30))
as
if exists(select * from D1.dbo.sysobjects
where type = 'U ' and name = @objectname)
begin exec ( 'drop table D1.dbo. '+@objectname) end

if exists(select * from D1.dbo.sysobjects
where type = 'V ' and name = @objectname)
begin exec northwind.dbo.sp_DCview 0,@objectname end

exec northwind.dbo.sp_DCview 1,@objectname

go

這樣就可以實現目的了。還有如果要判斷是否有名稱為XXX的某一個試圖或者是表的存在還可以用
object_id()這個函數,比如上面的判斷條件可以改為:
if object_id(@objectname, 'V ') is not null
具體可以參考SQL Online book.



------解决方案--------------------
1.利用sysobject系统表来获取某个视图或表是否存在,然后利用SQL的删除命令来将其删除

2.利用syscomments系统表来获取指定视图的内容,如果你创建视图时不依照原视图来创建,也可以忽略此步