# 2021-02-01 SQL Training Day 3 ## Views 在建 View 的時候,用的物件都必須存在,被儲存的是物件,而不是語法 ```=sql create view vw as select * from t -- 不應該用 select * go alter table t add c2 int select * from vw -- c2 不會出現 exec sp_refreshview 'vw' select * from vw ``` 資料凍結的時候建 indexed view 可加快查詢/報表執行速度,適合用在 BI sys information_schema -- 跨不同 DB 種類存取時,要有一致的 DB 架構資訊用的 view 可直接 alter,不需要 drop 再 create(避免安全設定被刪除) ```=sql create or alter ``` WITH SCHEMABINDING -- 下層的 schema 就不能動了 ```=sql create or alter view vw with SCHEMABINDING as select c1,c2 from dbo.t where c1>10 go ``` WITH CHECK option -- 不符合 view 的條件不能操作 ```=sql create table t(c1 int, c2 int) go create or alter view vw as select c1,c2 from dbo.t where c1>10 with check point go insert t values (8, 10) ``` ### Ownership Chains and Views ```=sql create user u without login create user v without login drop table if exists t create table t(c1 int, c2 int) go create or alter view vw as select c1 from dbo.t go grant select on vw to u insert t values(1,1) exec('select user.* from vw') as user = 'u' exec('select user.* from t') as user = 'u' alter authorization on t to v exec('select user.* from vw') as user = 'u' exec('grant select on t to u') as user = 'v' exec('select user.* from vw') as user = 'u' ``` ## Stored Procedures ```=sql declare @sql='select * from northwind.dbo.customers where countyr =''' + 'usa' + '''' exec (@sql) --->此寫法不佳 (會有 sql injection) declare @sql nvarchar(max) = 'select * from northwind.dbo.customers where countyr=@country' declare @sql2 nvarchar(max) = 'exec northwind.dbo.sp_executesql N''' + @sql + ''' ,N''@countyr nvarchar(50)'' ,''usa''' exec(@sql2) --->較佳寫法 ``` ```=sql create or alter proc sp1 as begin tran select @@TRANCOUNT exec sp2 select @@TRANCOUNT commit tran -- @@TRANCOUNT - 1 go create or alter proc sp2 as begin tran select @@TRANCOUNT rollback tran -- @@TRANCOUNT 歸零 begin tran go exec sp1 --->會有兩個錯誤 ``` ```=sql set nocount on -- (8 rows affected) 這種回應就不會出現 ``` 子 context 的設定不影響父 context 跑 SP 的時候會建立子 context,跑完就會結束此子 context ```=sql declare @p2 int=111,@p33 int,@ret int exec @ret=sp default,@p2,@p3 output select @ret,@p3 -->by position declare @p22 int=111,@p33 int,@ret int exec @ret=sp @p3=@p33 output,@p2=@p22 select @ret,@p33 -->by name ``` 加密前資料:應在 user 手上 加密後資料:應在 DB,DBA 手上 加密演算法:應在系統,AP 手上 加密的鑰匙:應在安全官手上 ## User defined function ![](https://i.imgur.com/fJZ9AXo.png) 選擇要的 ![](https://i.imgur.com/BLK7VqE.png) function 不可增、刪、修資料表 ```=sql use tempdb create table t3(c1 nvarchar(10)) alter table t3 add(c2 as substring(c1,2,1)) create index idx on t3(c2) alter table t3 add c3 as rand() create index idx2 on t3(c3) select * from t3 where substring(c1,2,1)='a' ``` ## SQL Server Security ```=sql drop login l create login l with password='password',check_pollicy=off create user l for login l ``` 授權是授權在 user 上,不是在 login 上 Partially Contained Databases: 換 server 時帳密可以帶著走 ![](https://i.imgur.com/0fqu2X2.png) ## Authorizing Users to Access Resources ```=sql use tempdb drop user u drop user v create user u without login create user v without login go create schema s go create table s.t(c1 int) go insert s.t values(1) create role r grant select on schema::s to r exect('select user.* from s.t') as user='u' alter role r add member u deny select on s.t to u revoke select on s.t to u role bades security row level security ``` DENY > GRANT > REVOKE ```=sql create server role s use master grant control server to s create login l2 with password='password',check_policy=off alter server role s add member l2 exec('create database demo') as login='l2' deny create any database to l2 drop database demo exec('create database demo') as login='l2' alter server role sysadmin add member l2 -- 之後就不做任何檢查 exec('create database demo') as login='l2' ```