web-dev-qa-db-ja.com

存在する場合はビューをドロップ

最初にビューをドロップしてから作成するスクリプトがあります。私はテーブルをドロップする方法を知っています:

IF EXISTS (SELECT * FROM sys.tables WHERE name = 'table1' AND type = 'U') DROP TABLE table1;

だから私はビューについても同じことをしました:

IF EXISTS (SELECT * FROM sys.views WHERE name = 'view1' AND type = 'U') DROP VIEW view1;
create view1 as(......)

そして、私はエラーになりました:

「CREATE VIEW」は、クエリバッチの最初のステートメントである必要があります。

26
4est

存在する構文が間違っているため、以下のようにDDLを分離する必要があります

if exists(select 1 from sys.views where name='tst' and type='v')
drop view tst;
go

create view tst
as
select * from test

以下のようなobject_idを使用して、存在テストを確認することもできます

if object_id('tst','v') is not null
drop view tst;
go

create view tst
as
select * from test

SQL 2016では、以下の構文を使用して削除できます

Drop view  if exists dbo.tst

SQL2016 CU1から、以下を行うことができます

create or alter view vwTest
as
 select 1 as col;
go
75
TheGameiswar

エラーについて

'CREATE VIEW' must be the first statement in a query batch.

Microsoft SQL Serverには、CREATE VIEWをバッチ内のonlyステートメントにするという風変わりな要件があります。これは、CREATE FUNCTIONなどの他のいくつかのステートメントにも当てはまります。これはnotCREATE TABLEのtrueなので、図に進みます…

解決策は、スクリプトを小さなバッチでサーバーに送信することです。これを行う1つの方法は、単一のステートメントを選択して実行することです。これは明らかに不便です。

より便利な解決策は、クライアントに小さな分離バッチでスクリプトを送信させることです。

GOキーワードは厳密にはSQLコマンドではありません。そのため、実際のSQLコマンドのようなセミコロンで終了することはできません。代わりに、この時点でスクリプトを中断し、その部分をバッチとして送信するようにクライアントに指示します。

その結果、次のような記述になります。

DROP VIEW IF EXISTS … ;
GO
CREATE VIEW … AS … ;
GO

私が遭遇した他のデータベースサーバー(PostgreSQL、MySQL、Oracle、SQLite)のいずれにもこの癖はありません。そのため、要件はMicrosoftのみであるようです。

2
Manngo
DROP VIEW if exists {ViewName}
Go
CREATE View {ViewName} AS 
SELECT * from {TableName}  
Go
1
Anwar Ul Haq

スキーマにも対応するには、SQL 2014でこの形式を使用します

if exists(select 1 from sys.views V inner join sys.[schemas] S on  v.schema_id = s.schema_id where s.name='dbo' and v.name = 'someviewname' and v.type = 'v')
  drop view [dbo].[someviewname];
go

そして、ストアドプロシージャを実行するためにそこに放り出しました。

if exists(select 1
          from sys.procedures p
          inner join sys.[schemas] S on p.schema_id = s.schema_id
          where
              s.name='dbo' and p.name = 'someprocname'
          and p.type in ('p', 'pc')
  drop procedure [dbo].[someprocname];
go
1
user230910