블로그 이미지
redkite

카테고리

분류 전체보기 (291)
00.SI프로젝트 산출물 (0)
00.센터 운영 문서 (0)
01.DBMS ============.. (0)
01.오라클 (117)
01.MS-SQL (15)
01.MySQL (30)
01.PostgreSql (0)
01.DB튜닝 (28)
====================.. (0)
02.SERVER ==========.. (0)
02.서버-공통 (11)
02.서버-Linux (58)
02.서버-Unix (12)
02.서버-Windows (2)
====================.. (0)
03.APPLICATION =====.. (11)
====================.. (0)
04.ETC =============.. (0)
04.보안 (5)
====================.. (0)
05.개인자료 (1)
06.캠핑관련 (0)
07.OA관련 (1)
Total
Today
Yesterday

달력

« » 2024.5
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

공지사항

최근에 올라온 글

### 백업 본 설정 및 복구(*** MDF  파일 삭제 된 후 마지막 Tailog--트랜잭션 로그 백업 필히 작업 후 복구 작업 시작)

** 복구 모델 전체 / 단순(트랜잭션 로그는 백업 안됨--noarchive mode)


drop database zDB

go


create database zDB

go

use zdb

go

create table T1 (id int)

go

-- 0. 백업폴더 생성

insert into T1 values (10),(20),(30)

select * from T1

go

-- 1. 전체백업

insert into T1 values (40),(50),(60)

select * from T1

go

-- 2. 차등백업

insert into T1 values (70),(80)

select * from T1

go

-- 3. 로그백업

insert into T1 values (90),(100)

select * from T1

go

-- 4. 차등백업

insert into T1 values (200),(300)

select * from T1

go


-- 장애

 - 데이터베이스 오프라인


 alter database zDB set offline


 - zDB.mdf 삭제

 - 데이터베이스 온라인


alter database zDB set online


-- Tail-Log 백업 ********


 backup log zDB to disk='c:\drive\zDB_last3.bak'

with no_truncate, init --(비상시백업,백업매체초기화)

-- 복원


-- 1. 기존 백업본을 통한 복원 (옵션: With norecovery)

--> 복원중 표시되고, 뒤에 복원을 또 할 수 있음.

-- 2. Tail-Log 백업본을 통한 복원 (옵션: With recovery)

--> 복원 완료를 의미, 뒤에 복원을 할 수 없음.

-- 확인

use zDB

select * from T1




## Shrink 테스트


ShrinkLog.sql





 ### 잠금의 단위

 

 - RID : 테이블에 있는 한 행을 잠그기 위한 행 ID입니다. 

 - 키(Key) : 인덱스에 있는 행 잠금입니다. 

 - 페이지(Page) : 8킬로바이트(KB) 데이터 페이지 또는 인덱스 페이지입니다. 

 - 익스텐트(Extent) : 인접한 여덟 개의 데이터 페이지 또는 인덱스 페이지 그룹입니다. 

 - 테이블(Table) : 모든 데이터와 인덱스가 포함된 전체 테이블입니다.  

 - 데이터베이스(DB) : 데이터베이스입니다. 




 ### 잠금의 종류


 - 공유(S) : (Shared Lock) SELECT 문처럼 데이터를 변경하거나 

업데이트하지 않는 작업(읽기 전용 작업)에 사용합니다. 

공유 잠금을 형성하여 다른 트랜잭션에 의해 현재의 데이터가 

데이터가 변경되지 못하도록 합니다.  


 - 업데이트(U) : (Update Lock) 데이터를 UPDATE 하기 위해 

Exclusive Lock을 형성하기 전에 미리 걸어주는 잠금입니다. 

즉, "곧 변경할테니까 접근하지 마라!" 라는 의미로 보시면 됩니다.  


 - 단독(X) : (Exclusive Lock)  INSERT, UPDATE, DELETE와 같은 

데이터 수정 작업에 사용합니다. 

여러 개의 업데이트 작업이 같은 리소스에 대해 동시에 

이루어지지 못하게 합니다.

데이터 읽기 조차도 못하게 됩니다. 


 - 내재 : (Intent Lock)  잠금 계층 구조를 만드는 데 사용합니다. 

내재된 잠금의 종류에는 내재된 공유(IS) 잠금, 

내재된 단독(IX) 잠금, 공유 및 내재된 단독(SIX) 잠금이 있습니다. 

예를 들어 레코드에 공유잠금(S)이 형성되어 있으면 

이 레코드를 포함하는 테이블은 내재된 공유잠금(IS)를 형성하여 

"레코드에 공유 잠금이 형성되어 있으니 너희들은 나에게 

단독 잠금(Exclusive Lock) 걸면 안돼!" 라고 알려주는 것입니다. 


 - 스키마 : (Schema Lock)  테이블의 스키마에 종속되는 작업이 실행될 때 사용합니다. 

스키마 잠금의 종류에는 스키마 수정(Sch-M)과 스키마 안전성(Sch-S) 

두 가지가 있습니다.  


 - 대량 업데이트(BU) : (Bulk Update Lock) 데이터를 테이블로 

대량 복사하는 경우와 TABLOCK 참고가 지정된 경우 사용합니다. 





 ### 고립화 수준(Isolation Level) 


 - 아직 UPDATE가 완료 되지 않았기 때문에 UPDATE 되기전 


잘못된 데이터를 읽을 위험이 있으므로 이를 방지하기 위함입니다. 


하지만 원한다면 UPDATE 작업이 완료되지 않은 상태의 데이터를 


다른 세션에서 읽을 수 있도록 할 수 있습니다.



 - 트랜잭션의 고립화 수준이란 여러개의 트랜잭션이 동시에 수행 될 때 


잠금 충돌이 발생 하면 이를 어떻게 처리할지에 대한 문제라고 보시면 됩니다. 


고립화 수준을 어떻게 하느냐에 따라 다른 결과를 볼수 있게 됩니다.



 - 두 세션의 잠금 현상을 이용해보도록 하겠습니다. 


한 세션이 UPDATE 중일 다른 세션은 이 UPDATE 작업이 완료 될때까지 


그 데이터를 대상으로 검색을 할 수가 없었습니다. 


왜냐하면 현재 진행중인 UPDATE 작업이 COMMIT 될 지 


ROLLBACK 될 지 아직 모르기 때문에 완벽하지 않은 데이터를 보는것을 


방지하도록 하기 위해서입니다. 


하지만 다음과 같이 트랜잭션의 고립화 수준을 별도로 지정하게 되면 


결과는 달라집니다.



  --> SET TRANSACTION ISOLATION LEVEL 

   READ UNCOMMITTED


   GO 



 


 ### 고립화 수준(Isolation Level)의 종류


 - 고립화 수준은 낮을 수록 성능은 좋아집니다. 


하지만 데이터의 무결성은 깨어질 가능성이 높습니다. 


트랜잭션의 고립화 수준에는 다음과 같이 4가지 종류가 있습니다.



 1) READ UNCOMMITTED

  : Trouble

 - DirtyRead

 - NonRepeatable Read

 - Phantom Read


고립화 수준에서 가장 낮은 수준입니다. 


즉, DIrty Page를 읽어오게 되는 것입니다. 



2) READ COMMITTED (Default)

: Trouble

 - NonRepeatable Read

 - Phantom Read


  Dirty Page를 읽는, 즉 DIrty Read를 방지합니다. 


  별도의 고립화 수준을 설정하지 않았거나 

READ COMMITTED를 설정하게 되면 


  COMMIT 하지 않은 트랜잭션이 이용한 자원에 대해 

트랜잭션이 완료되어야 


(= 잠금이 해제되어야) 데이터를 읽을 수 있습니다.



3) REPEATABLE READ

: Trouble

 - Phantom Read


SQL Server는 기본적으로 같은 값을 반복적으로 가져 올 경우 이전 값과 


항상 같다는 것을 보장하지 못합니다. 


이러한 것을 Nonrepeatable Read라고 하는데 이러한 문제는 


한 트랜잭션 내에서 같은 SQL문을 여러번 사용할 경우 내부적으로 


공유 잠금(S)를 트랜잭션 종료시까지 유지하지 않기 때문입니다. 


REPEATABLE READ 고립화 수준은 이러한 문제를 해결할 수 있는 고립화 수준입니다. 


트랜잭션이 완료될 때까지 공유 잠금을 유지하여 여러번 같은 데이터를 읽어도 


항상 같은 값이 얻어지도록 합니다.




주의해야할 사항은 REPEATABLE READ가 설정되면 


원래 읽었던 데이터에 대하여서는 항상 같은 값이 유지 되지만 


새로 추가되는 데이터를 막을 수는 없습니다. 



예를 들어 특정 조건에 만족한 레코드가 5개였으면 


이 5개의 레코드는 언제든 같은 값을 보이게 되지만 


다른 트랜잭션에 의해 이 조건을 만족하는 새로운 레코드가 추가되면 


원래 없었던 새로운 레코드가 보이게 됩니다. 


이러한 것을 Pantom Read라고 합니다.





4) SERIALIZABLE

: Trouble

 - Nothing


가장 높은 고립화 수준으로 REPEATABLE READ 


고립화 수준이 막지 못하는 Phantom Read까지 방지해줍니다. 


완벽한 데이터베이스의 일관성은 유지해 주지만 


잠금을 유지하기 위하여 오버헤드는 증가하게 됩니다.


### 잠금크기와 관련된 잠금힌트


1) ROWLock : 공유 행 잠금

2) PAGLock : 공유 페이지 잠금

3) TABLock : 공유 테이블 잠금

4) TABLockX : 단독(Exclusive) 테이블 잠금


### 그밖의 잠금힌트


1) XLock : 단독(Exclusive)잠금 지정

2) UpdLock : 업데이트 잠금 지정

3) ReadPast : 잠긴 행은 건너뛰고 잠기지 않는 행들만 접근 

-> Read Commited 격리수준에서만 적용


### 커서(Cursor)에 대한 요약 정리

커서란?

- 데이터 처리는 집합단위로 이루어지기도 하지만 조건에 따라서는 행 단위로 처리하기도 한다.

- 행 단위의 데이터 처리시 커서를 사용한다.


커서의 장점

- 데이터를 행 단위로 처리할 수 있음.


커서의 단점

- 데이터 처리 속도가 느려짐.(SQL문에 비해 느림)


1.1 커서의 종류

- 서버커서(Server Cursor), 클라이언트 커서(Client Cursor)


서버커서(Server Cursor)

- T-SQL 커서와 API 커서로 나뉨


T-SQL 커서 란?

- 결과 집합을 만드는 T-SQL스크립트, 트리거, 저장 프로시저에서 사용

- 변수로 한 열을 할당받는다.(변수의 크기는 열의 데이터 타입과 데이터를 모두 받을 수 있을 만큼 선언)


API 커서란?

- OLEDB, ODBC, ADO를 이용하여 SQL 문의 결과 집합에서 커서 매핑.


클라이언트 커서란?

- ODBC에서 지원하는 커서, 결과 집합을 클라이언트 캐쉬에 저장(읽기전용)


1.2 커서의 작업

- DECLARE를 이용한 커서 선언

- OPEN을 이용한 커서 열기

- FETCH를 이용한 데이터 불러오기

- CLOSE를 이용한 커서 닫기

- DEALLOCATE를 사용ㅇ한 커서 선언 제거


1.3 커서의 ANSI 문법

- Declare 커서 이름 [ INSENSITIVE ] [ SCROLL ] CURSOR

   FOR SELECT 구문

   [ FOR { READONLY | UPDATE [ OF 컬럼명 [......N]] } ]


- INSENSITIVE : 커서에서 사용할 데이터를 임시로 복사해 주는 커서를 정의

                커서에서 정의된 데이터는 tempDB에 저장됨.

                잠금이 생김, 동시성 저하.

- SCROLL : 모든 인출 옵션 사용이 가능

           인출 옵션(FIRST, LAST, PRIOR, NEXT, RELATIVE, ABSOLUTE)

           인출 옵션이란? 데이터를 불러올 행을 이동하는 방식


- SELECT 구문 : 일반적인 select 구문 형식을 따름

- READ ONLY : 커서를 통한 데이터 변경 및 삭제를 방지, DELETE, UPDATE 기능을 무시.


1.4 커서의 T-SQL 문법

- DECLARE 커서 이름 CURSOR [ LOCAL | GLOBAL ]

 [ FORWARD_ONLY | SCROLL ]

 [ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ]

 [ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ]

 [ TYPE_WARING ]

 FOR SELECT 구문

  [ FOR UPDATE [ OF 컬럼명 [ ,......N]]]


- LOCAL: 커서의 범위를 로컬로 지정(로컬변수)

- GLOBAL: 커서의 범위를 전역을 지정(전역변수)

- FORWARD_ONLY: "전진만 있되 후퇴는 없도다.", 유일한 명령 옵션은 FETCH_NEXT

- SCROLL: 모든 인출 옵션(FIRST, LAST, PRIOR, NEXT, RELATIVE, ABSOLUTE)를 사용하도록 지정

- STATIC: 수정이 안됨(임시커서)

- KEYSET: 커서에 포함되는 행과 멤버와 순서가 고정되도록 지정.

- DYNAMIC: 인출할 때 마다 행의 데이터 값과 순서, 멤버가 변경됨, 동적 커서

- FAST_FORWARD: 성능 최적화가 설정된 FORWARD_ONLY, READ_ONLY 커서를 지정.

- READ_ONLY: 데이터에 대한 변경 및 삭제 방지, UPDATE, DELETE 구문의 WHERE CURRENT OF 절에서 이키를 사용할 수 없음

- SCROLL_LOCKS: 위치 지정 업데이트나 삭제가 성공하도록 지정


-- Declare 구문지정

DECLARE YearPlan_Cur CURSOR FOR

  SELECT CustCode, WkCnt, DeptCode, Week, Day, SMethodYN, DaN

  FROM RM_YearPlan

  WHERE WkCnt = '1'


-- OPEN 구문

OPEN YearPlan_Cur


-- FETCH 구문

FETCH NEXT FROM YearPlan_Cur

WHILE @@FETCH_STATUS = 0

 BEGIN

  FETCH NEXT FROM YearPlan_Cur

 END


-- CLOSE 구문

CLOSE YearPlan_Cur


-- 커서 해제

DEALLOCATE YearPlan_Cur



Cursor.sql



Posted by redkite
, |

### INDEX 생성 시

1) 조회 빈도

2) 데이터 입력이 빈번한가


3) 범위형 쿼리(CI 가 좋음)

4) 포인트 쿼리(CI/NCI 관게 없음)

5) 사이즈


### INDEX  활용

 1)업무분석


 - 조회컬럼

 - 정렬컬럼

 - 컬럼에 대한 프로세스 


 2) 인덱스가 걸리는 컬럼의 사이즈


 - 컬럼의 사이즈 -> 데이터페이지 -> CI의 인덱스 페이지 (CI의 키값)

-> NCI 의 인덱스 페이지


 3) 한 테이블의 컬럼의 숫자를 고민해보세요 


 - Lock, Dead Lock


 4) 복합인덱스 => 검색 데이터 사용량 빈도 ?


 - '풍물'동아리에 있는 학생의 수 => 동아리 코드 + 학생번호

 - '홍길동'학생이 가입한 동아리의 수 => 학생번호 + 동아리코드


 5) 커버드 쿼리의 이용을 고민해보자


 - 커버드 쿼리 : 조회의 조건과 대상 컬럼이 인덱스에 있고,

그 인덱스로 질의를 하는 것


 - Size와 페이지분할

<- 복합인덱스(4)

<- 커버드쿼리(2+2)


 6) 파일그룹을 이용하자


 - 파일그룹을 이용해서 분한테이블/분할인덱스를 만듦으로써


   한개의 테이블에 걸리는 인덱스의 높이/깊이를 


   감소시키면서 성능을 향상시킨다


 7) 인덱스 활용쿼리 디자인


 - 인덱스가 정의된 열을 가공하지 말아야 한다

 - Like 키워드의 검색문자열 앞에 와일드 카드 사용을 피한다



### Index 생성 고려사항


 1. 조회가 빈번하게 일어나지 않는 테이블에 Index 생성하지말것


 2. Where 절 뒤에 오는 컬럼을 대상으로 Index를 고려해야 함


 3. 밀도가 높은 컬럼은 Index를 걸지 말것 예)성별[남,녀]


 4. Index를 재구성, 재작성을 통해서 재정렬을 할수 있음


- 재구성 (Re-Organization) : 리모델링

- 재작성 (Re-Build)   : 재건축


 5. Index 를 설정한다고 해도 반드시 Unique 한것은 아니다


 6. PK는 Clustered Index를, UQ는 Non-Clustered Index가 기본적으로


설정된다


 7. Index가 필요하다면,


포인트 쿼리, 범위쿼리, 추가(순차적/비순차적), 크기


 8. Clustered Index 

- 범위쿼리와 순차적 Data입력/수정/삭제에 바람직

- Table당 한개만 생성 가능


 9. Non-Clustered Index

- 비순차적 Data입력/수정/삭제와 포인트쿼리에 바람직

- Table당 249개 생성 가능


10. Index Key 설정 시, 같은 조건이면 크기(Size) 작은 것으로 할것


11. Scan/Seek


- Table Scan : Heap의 상태에서 전체 페이지 조회

- Clustered index Scan : CI로 설정된 상태에서 전체

페이지 조회


- Clustered index Seek : CI로 설정된 상태에서 

Index를 통한 조회


- Index Seek : NCI로 설정된 상태에서 Index를 통한 조회


12. 외래키(Foreign Key)에 Index를 설정할 때, 성능이 좋아질 

확률이 많다


13. alter index 지원은 SQL Server 2005 부터 가능


14. 단일컬럼 Index 


- 복합 컬럼 index : 설정된 컬럼 모두 Key값


create nonclustered index idx_cust_N

on cust_N (customerid,추가컬럼)



- 포괄열 index    : 포괄열은 Key값은 아님

 : NCI 에서만 가능함


create nonclustered index idx_cust_N

on cust_N (customerid) include (추가컬럼)


15. 채우기비율 설정


   -채우기비율(FillFactor) : Index Leaf Page에만 영향

   -인덱스패딩(PAD_INDEX)  : ON 하면 Leaf외에도 채우기비율 적용



### Cover Index

-- Index Lookup --


if OBJECT_ID('Orders') is not null

drop table Orders

go


select * into Orders from Northwind.dbo.Orders

go


select * from Orders


Exec sp_helpindex Orders

create nonclustered index idx_ord_01 

on Orders(CustomerID) -- nchar(5)

go


set statistics profile on

set statistics io on

set statistics time on


select * from Orders

go


-- Index를 타고 있는가? --

select * 

from Orders

where CustomerID = 'ERNSH'

and ShipVia = 3

go


-- Index 강제 적용 --

select ShipVia 

from Orders with(index(idx_ord_01))

where CustomerID = 'ERNSH'

and ShipVia = 3

go


exec sp_helpindex orders


-- NC Index 재생성 -- (인덱스 포괄열 포함)

drop index Orders.idx_ord_01

create nonclustered index idx_ord_01 

on Orders(CustomerID) include (ShipVia)

go


-- NC Index 추가 생성 --

drop index Orders.idx_ord_02

create nonclustered index idx_ord_02 

on Orders(EmployeeID,ShippedDate)

go

Exec sp_helpindex Orders

go

-- 검색 --

Select * from Orders

where EmployeeID = 4

and ShippedDate >= CONVERT(datetime,'19960101',112)

and ShippedDate < CONVERT(datetime,'19980101',112)

go

-- Hint 사용 --

Select * from Orders with(index(idx_ord_02))

where EmployeeID = 4

and ShippedDate >= CONVERT(datetime,'19960101',112)

and ShippedDate < CONVERT(datetime,'19980101',112)

go


-- NC Index 제거 및 CI 추가 생성 --

drop index Orders.idx_ord_02

create clustered index idx_ord_03 

on Orders(EmployeeID,ShippedDate)

go

Exec sp_helpindex Orders

go

-- CI를 통한 검색 --

Select * from Orders

where EmployeeID = 4

and ShippedDate >= CONVERT(datetime,'19960101',112)

and ShippedDate < CONVERT(datetime,'19980101',112)

go


--별도] NC Index 강제 적용: Key Lookup을 하고 있는가? --

select * 

from Orders with(index(idx_ord_01))

where CustomerID = 'ERNSH'

and ShipVia = 3

go

-- 페이지 I/O 2개 <-- 논리적 읽기 수 2로 알수 있음

Select COUNT(*)

from Orders 

where CustomerID like 'Bo%'

go


-- Key Lookup의 횟수는 총 34회

-- 페이지 I/O가 2개 이므로, (81-2)

-- Key Lookup이 읽었던 페이지 수는 79페이지

Select CustomerID,ShippedDate,Freight

from Orders with(index(idx_ord_01))

where CustomerID like 'Bo%'

go


--> Heap의 상태에서 RID Lookup을 통한

--> 페이지 읽기의 수보다는 늘어난 상태

-- NCI 제거 후, 커버된 Index 생성 --

drop index Orders.idx_ord_01

go

create index idx_ord_04 on Orders (CustomerID)

include (ShipVia,Freight)

go


-- NCI 검색 : 읽기 페이지수 2개 --

Select CustomerID,ShippedDate,Freight

from Orders with(index(idx_ord_04))

where CustomerID like 'Bo%'

go

--> NCI Leaf레벨의 Index 페이지에 

--> ShippedDate,Freight 가 포함되어

--> Key Lookup 이 일어나지 않음




### INDEX Tuning

-- create database inDB


use inDB


select ProductID, Name, Color, Size, Weight

 into pTbl from Adventureworks.Production.Product


select SalesOrderDetailID as OrderID, ProductID, OrderQty,

unitPrice, LineTotal as Total

 into oTbl from Adventureworks.Sales.SalesOrderDetail


-- Create Constraint


Alter Table pTbl

 add constraint pk_pTbl Primary key (ProductID)


Alter Table oTbl

 add constraint pk_oTbl Primary key (OrderID)


Alter Table oTbl

 add constraint fk_pTbl 

foreign key (ProductID) references pTbl(ProductID)


--

select count(*) from pTbl

select count(*) from oTbl


-- 

Select Top(5)* from pTbl 

Select Top(5)* from oTbl


Select * from pTbl --> 7 페이지

Select * from oTbl --> 664 페이지


set statistics IO on

-- Tunning Advisor --

select p.ProductID, p.name, 

sum(o.orderqty) as [oTotal],sum(o.Total) as [Total]

from pTbl P inner join oTbl O on p.ProductID = o.ProductID

group by p.ProductID, p.name

having p.ProductID = '717';


select * from pTbl where color='Silver' order by name;


select ProductID, Total from oTbl order by Total Desc;


## 데이터 베이스 엔진 튜닝 관리자 실행 후 사용될 쿼리문 수행



### Nested Loop Join
set statistics profile on
-- [Nested Loop JOIN ]
select name,addr,mobile1,mobile2
from userTbl u, buyTbl b
where u.userID = b.userid
and prodName = '모니터'

select prodName,price,amount
from userTbl u, buyTbl b
where u.userID = b.userid
and name = '박주영'

-- [LOOP JOIN : 중첩루프조인]

SELECT * 
FROM Sales.Customer AS c
INNER JOIN Sales.CustomerAddress AS ca
ON c.CustomerID = ca.CustomerID
OPTION (LOOP join);
go

-- [Merge Join: 병합조인]

SELECT * 
FROM Sales.Customer AS c
INNER JOIN Sales.CustomerAddress AS ca
ON c.CustomerID = ca.CustomerID
OPTION (MERGE join, FORCE ORDER);
GO

SELECT * 
FROM Sales.Customer AS c
INNER JOIN Sales.CustomerAddress AS ca
ON c.CustomerID = ca.CustomerID
OPTION (MERGE join);
GO  

SELECT * 
FROM Sales.CustomerAddress AS ca
INNER JOIN Sales.Customer AS c
ON c.CustomerID = ca.CustomerID
OPTION (MERGE join);
GO

-- [Hash Join] --

SELECT * 
FROM Sales.Customer AS c
INNER JOIN Sales.CustomerAddress AS ca
ON c.CustomerID = ca.CustomerID
OPTION (hash join, FORCE ORDER);
GO

SELECT * 
FROM Sales.Customer AS c
INNER JOIN Sales.CustomerAddress AS ca
ON c.CustomerID = ca.CustomerID
OPTION (hash join);
GO



### Hash Match Join
-- Hash Match(Aggregate)
-- Stream Aggregate 

USE indb
GO

IF OBJECT_ID('TEST','U') IS NOT NULL
       DROP TABLE TEST
GO

CREATE TABLE TEST( A INT NOT NULL, B INT NOT NULL)
GO
-- NCI 생성

CREATE INDEX NC_TEST_A ON TEST(A)
GO

SET NOCOUNT ON
GO

DECLARE @I INT = 1
WHILE(@I <= 10000)
BEGIN
       INSERT INTO TEST SELECT @I, CONVERT(INT,RAND()* 1000) +1
       SET @I = @I + 1
END

SET NOCOUNT OFF
GO

SELECT  B
FROM TEST
GROUP BY B

SELECT A
FROM TEST
GROUP BY A

-- 기존 Index 삭제 후, Unique & NCI 생성

DROP INDEX TEST.NC_TEST_A
GO

CREATE UNIQUE INDEX NC_TEST_A ON TEST(A)
GO

SELECT A
FROM TEST
GROUP BY A

---------------------------------------------
-- Table 삭제 후, 재생성

IF OBJECT_ID('TEST','U') IS NOT NULL
     DROP TABLE TEST
GO

CREATE TABLE TEST( A INT NOT NULL, B INT NOT NULL)
GO

SET NOCOUNTON
GO

DECLARE @I INT = 1
WHILE(@I <= 2519)
BEGIN
       INSERT INTO TEST SELECT @I, @i
       SET @I = @I + 1
END

SET NOCOUNTOFF
GO

SELECT B
FROM TEST
GROUP BY B


### SQL Profiler 테스트

select * from Cust_A
select * from Cust_c
select * from Cust_n
go

select * from Cust_A
go
select * from Cust_c
go
select * from Cust_n
go

select * from Cust_A;
select * from Cust_c;
select * from Cust_n;
go



Posted by redkite
, |


 ### 트리거 (Trigger)


 1) 목적 : 데이터 무결성과 일관성 유지

 

 2) 종류:

- DML 트리거 : insert, update, delete

- DDL 트리거 : create, alter, drop


 3) 옵션:

- After : 실행 후(트랜잭션 로그가 계속 남음)

- Instead of : 실행 전(트랜잭션 로그가 안남음)


 4) 참고: 가상 테이블 (inserted, deleted)



use sqldb

create Table TA

 ( id int identity Primary key,

name char(8))


create Table TB

 ( id int identity Primary key,

name char(8))


insert into TA values ('jhAn')

insert into TB values ('jhAn')


select * from TA

select * from TB


create Trigger Trg_A on TA

 instead of insert

 as

rollback

go


create Trigger Trg_B on TB

 after insert

 as

rollback

go


drop Trigger Trg_A

drop Trigger Trg_B


Instead Vs. After 차이점




## Procedure Compile

drop Table spTable


select * into spTable 

from AdventureWorks.Sales.Customer

order by rowguid


select * from spTable


create index idx_spTbl on spTable (customerid)

Exec sp_helpindex spTable


--set statistics time off

set statistics IO on


select * from spTable where customerID < 10

select * from spTable where customerID < 1000


create Proc usp_1

@id int

as

select * from spTable where customerID < @id



Exec usp_1 10 --with recompile


Exec usp_1 1000 --with recompile


DBCC Freeproccache


alter Proc usp_1

@id int

with recompile

as

select * from spTable where customerID < @id



## 데이터 형식 우선순위 ##


1.     사용자 정의 데이터 형식(가장 높음)

2.     sql_variant

3.     xml

4.     datetimeoffset

5.     datetime2

6.     datetime

7.     smalldatetime

8.     date

9.     time

10.   float

11. real

12.   decimal

13.   money

14.   smallmoney

15.   bigint

16.   int

17.   smallint

18.   tinyint

19.   bit

20.   ntext

21.   text

22.   image

23.   timestamp

24.   uniqueidentifier

25.   nvarchar(nvarchar(max) 포함)

26.   nchar

27.   varchar(varchar(max) 포함)

28.   char

29.   varbinary(varbinary(max) 포함)

30.   binary(가장 낮음)


### 인덱스 생성 테스트 ###
use AdventureWorks
select * from AdventureWorks.sales.customer

create database indb

use indb
select * into Cust_A from AdventureWorks.sales.customer
select * into Cust_c from AdventureWorks.sales.customer
select * into Cust_n from AdventureWorks.sales.customer

select Top(5)* from Cust_A
select Top(5)* from Cust_C
select Top(5)* from Cust_N

Exec sp_helpindex cust_A
Exec sp_helpindex cust_C
Exec sp_helpindex cust_N

create Clustered index idx_cust_C
on cust_C (customerid)

create nonclustered index idx_cust_N
on cust_N (customerid)

set statistics io on
set statistics time on

select * from Cust_A where customerID < 1000
select * from Cust_C where customerID < 1000
select * from Cust_N where customerID < 1000


select * from Cust_A where customerID < 1000
select * from Cust_C where customerID < 1000
select * from Cust_N with(index(idx_Cust_N)) 
where customerID < 1000



### 형 변환 ##

use indb
go

select * from master.dbo.syscolumns
select * from tempdb.dbo.syscolumns
select * from model.dbo.syscolumns
select * from msdb.dbo.syscolumns

if OBJECT_ID('t_columns') is not null
drop table t_columns
go

select t.*
into t_columns
from 
(select CAST(1 as smallint)as dbid,* from master.dbo.syscolumns
union all
select CAST(2 as smallint)as dbid,* from tempdb.dbo.syscolumns
union all
select CAST(3 as smallint)as dbid,* from model.dbo.syscolumns
union all
select CAST(4 as smallint)as dbid,* from msdb.dbo.syscolumns
) t
go

select * from t_columns
go
select COUNT(*) as cnt from t_columns
go

create index idx_t_01 on t_columns (dbid,name)
go

Exec sp_helpindex t_columns

-----------------------------------------------
set statistics profile on
set statistics io on
set statistics time on
go

select * 
from t_columns 
-- Index Scan --
select * 
from t_columns 
where name = 'addr'

-- Index Seek --
select * 
from t_columns 
where name = 'addr'
and dbid in (1,2,3,4)
-- Index 제거 --

sp_helpindex t_columns

drop index t_columns.idx_t_01
go
-- index 추가 --
create index idx_t_02 on t_columns(name)
go

-- column 추가
select * from t_columns
go

alter table t_columns -- 자동증가값
add no_tmp int identity not null
go

alter table t_columns -- null 값
add no varchar(10)
go

-- 값 변경 null --> 자동증가값
update t_columns
set no = no_tmp
go

-- Index 추가
create index idx_t_03 on t_columns (no)
go

select * from t_columns
where name = 'rowsetid'

---------------------------------------
-- Explicit 형 변환 --
select * from t_columns
where SUBSTRING(name,1,8) = 'rowsetid'
go

select * from t_columns
where name like 'rowsetid'
go

-- Implicit 형변환 --
select * from t_columns
where no=1 --varchar(10)
go       
--> 데이터 우선순위 (Int > varchar) 
--> 변환 (varchar --> Int)
select * from t_columns
where no = CONVERT(varchar(10),1)
go
--> 암시적 변환 예
--> 날짜 char(8)
--> where 계약일자 = 20130311
--> 데이터 우선순위 (Int > char(8)) 
--> 변환 (char(8) --> Int)



### 인덱스 기본키 생성
use xDB
go

create table T1 (
a int,
b int,
c int)
go

Exec sp_help T1
Exec sp_helpindex T1
go

create table T2 (
a int Primary key,
b int,
c int)
go

Exec sp_help T2
Exec sp_helpindex T2
go

create table T3 (
a int Primary key,
b int Unique,
c int Unique)
go

Exec sp_helpindex T3
go

create table T4(
a int Primary key nonclustered,
b int Unique clustered,
c int Unique)
go

Exec sp_helpindex T4
go

create table T5(
a int Primary key nonclustered,
b int Unique clustered,
c int Unique clustered) --< 불가능
go

Exec sp_helpindex T5
go

create table T6(
a int Primary key nonclustered,
b int Unique nonclustered,
c int Unique nonclustered)
go

Exec sp_helpindex T6
go

## 인덱스 생성

exec sp_helpdb indb
go

if OBJECT_ID('empTbl') is not null
drop table empTbl
go

use inDB
create table empTbl(
empID int not null,
LastName nvarchar(20) null,
FirstName nvarchar(10) null,
HireDate datetime null
)

insert into empTbl
select EmployeeID, LastName, FirstName, HireDate
from Northwind.dbo.Employees
order by EmployeeID
go

select * from empTbl
go

-- Table에 Index 확인 --
Exec sp_helpindex empTbl
go

-- Index 생성 --> LastName
create index idx_empTbl_LastName on empTbl(LastName)
with (fillfactor = 1, pad_index = on)
go

-- index 아이디 확인 --
select index_id, name
from sys.indexes 
where object_id = object_id('empTbl')
go

-- ind ('Database 명','Table 명','Index 아이디')
--> Page Type : DataPage(1),IndexPage(2),IAM(10)
--> Index Level : 루트(2),브랜치(1),리프(0)
dbcc ind('inDB','empTbl',2)
go

-- dbcc page 앞에 실행해야 함
--> dbcc 명령들은 기본적으로 출력을 로그에만 남김
dbcc traceon(3604)
go
-- page('Database 명','파일번호','페이지번호','출력옵션[0~3]')
dbcc page('indb',1,118,3)
go

------- Index 생성 기초 ------------------
-----------------------------------------
-- Clustered Index 생성 --

Exec sp_helpindex empTbl
SP_SPACEUSED [empTbl] 
GO

alter table empTbl 
add constraint idx_emp_pk
primary key clustered (empID)
go

alter table empTbl
drop constraint idx_emp_pk
go


### 인덱스 정보 확인 ###
USE ADVENTUREWORKS
GO
SP_HELP [PERSON.ADDRESS] 
GO
SP_HELPINDEX [PERSON.ADDRESS] 
GO
USE ADVENTUREWORKS
GO
SELECT * FROM SYS.INDEXES 
WHERE OBJECT_ID = OBJECT_ID('PERSON.ADDRESS')
GO
SELECT * FROM SYS.INDEX_COLUMNS 
WHERE OBJECT_ID = OBJECT_ID('PERSON.ADDRESS')
GO
USE ADVENTUREWORKS
GO
SELECT * FROM SYS.DM_DB_INDEX_PHYSICAL_STATS 
(DB_ID(N'ADVENTUREWORKS'), OBJECT_ID(N'PERSON.ADDRESS'),
NULL, NULL , 'DETAILED')
GO
SELECT * FROM SYS.DM_DB_INDEX_OPERATIONAL_STATS 
(DB_ID(N'ADVENTUREWORKS'), OBJECT_ID(N'PERSON.ADDRESS'), NULL,
NULL)
GO
SELECT * FROM SYS.DM_DB_INDEX_USAGE_STATS 
WHERE OBJECT_ID = OBJECT_ID(N'PERSON.ADDRESS')
GO
SELECT INDEXPROPERTY(OBJECT_ID('PERSON.ADDRESS'), 
'PK_Address_AddressID','IsClustered')AS [Is Clustered],
INDEXPROPERTY(OBJECT_ID('PERSON.ADDRESS'),
'PK_Address_AddressID','IndexDepth') AS [Index Depth],
INDEXPROPERTY(OBJECT_ID('PERSON.ADDRESS'),
'PK_Address_AddressID','IndexFillFactor') AS [Fill Factor];
GO



### 인덱스 활용
USE ADVENTUREWORKS
GO

Exec sp_helpindex [SALES.SALESORDERDETAIL]
select * from SALES.SALESORDERDETAIL

drop index SALES_QTY_IDX on SALES.SALESORDERDETAIL
GO

set statistics io on

SELECT * FROM SALES.SALESORDERDETAIL 
WHERE ORDERQTY >= 35
GO

Exec sp_helpindex [SALES.SALESORDERDETAIL]

CREATE INDEX SALES_QTY_IDX ON SALES.SALESORDERDETAIL(ORDERQTY) 
GO

SELECT * FROM SALES.SALESORDERDETAIL 
WHERE ORDERQTY >= 35
GO
SELECT * FROM SALES.SALESORDERDETAIL
WHERE ORDERQTY - 5 >= 30
GO
USE ADVENTUREWORKS
GO
SP_HELPINDEX [PRODUCTION.PRODUCT] 
GO
SELECT NAME FROM PRODUCTION.PRODUCT 
WHERE NAME LIKE '%Blade%'
GO
SELECT NAME FROM PRODUCTION.PRODUCT
WHERE NAME LIKE 'Blade%'
GO



### 인덱스 비활성화
USE ADVENTUREWORKS
GO

select * from Person.Address

SP_HELPINDEX [PERSON.ADDRESS] 
GO
SP_SPACEUSED [PERSON.ADDRESS] 
GO

set statistics io on

select * from Person.Address
where StateProvinceID < 3

ALTER INDEX IX_ADDRESS_STATEPROVINCEID ON PERSON.ADDRESS 
rebuild -- 활성화
DISABLE  -- 비활성화
GO
SP_HELPINDEX [PERSON.ADDRESS] 
GO
SP_SPACEUSED [PERSON.ADDRESS]
GO
ALTER INDEX PK_Address_AddressID ON PERSON.ADDRESS 
DISABLE
GO
SP_SPACEUSED [PERSON.ADDRESS]
GO
ALTER INDEX IX_ADDRESS_STATEPROVINCEID ON PERSON.ADDRESS 
REBUILD WITH (ONLINE=ON)
GO
ALTER INDEX ALL ON PERSON.ADDRESS REBUILD 
GO
SP_SPACEUSED [PERSON.ADDRESS]
GO
ALTER INDEX IX_ADDRESS_STATEPROVINCEID ON PERSON.ADDRESS 
DISABLE
GO
SELECT IS_DISABLED FROM SYS.INDEXES
WHERE OBJECT_ID = OBJECT_ID('PERSON.ADDRESS')
AND NAME = 'IX_ADDRESS_STATEPROVINCEID'
GO
ALTER INDEX IX_ADDRESS_STATEPROVINCEID ON PERSON.ADDRESS
REBUILD WITH (ONLINE=ON)
-- ONLINE=ON (온라인 상태, 즉 Table Lock을 안 걸고 실행)
GO

Posted by redkite
, |

트랜잭션이란? 


데이터베이스의 논리적인 작업의 처리 단위이다.

여기서 작업이라 함은 일반적으로 데이터베이스에서의 데이터 입력,수정,

삭제 등을 말하는 것으로 데이터베이스에 변경사항을 유빌하는 행위를 말한다.

그리고 하나의 입력, 수정, 삭제 직업이 개별적인 트랜잭션으로 처리될 수도 있지만,

하나의 트랜잭션 내에서 여러 작업이 포함될 수도 있다.

그래서 트랜잭션읕 물리적이 아닌 논리적인 작업의 처리단위라고 하는 것이다.

그리고 트랜잭션의 기본 개념은 All or Nothing 이다.



 # 트랜잭션


-- 명시적 트랜잭션   : Begin(O),Commit(O)

-- 암시적 트랜잭션   : Begin(X),commit(O) ==> 오라클

-- 자동커밋 트랜잭션 : Begin(X),commit(X) ==> MS SQL Server



-- set implicit_transactions on


-- AA 창 --

select * from TC


begin tran

 update TC set id = 11 where id = 10

 update TC set id = 22 where id = 20

 update TC set id = 33 where id = 30

commit tran


select @@TRANCOUNT


-- BB 창 --

 use master

 Alter database sqlDB set allow_snapshot_isolation on

 set Transaction isolation level snapshot

  -- 잠금에 걸린 Tabble이라도 메모리(캐시)가 아닌 

-- 데이터 파일의 내용을 무조건 읽어올수 있도록 만들어 줌

select * from TC



# 체크포인트


체크 포인트(Check Point) 프로세스는 현재까지 메모리에서 진행된 모든 내용을 데이터 파 일과 로그 파일에 기록하는 프로세스로이다. 마치 워드나 엑셀 같은 프로그램에서 저장버튼 을 누르는 것과 같은 역할을 수행한다. 미러한 체크 포인트는 기본적으로 SQL Server가 1분마다 상황을 체크해서 많은 작업(많은 작업에 대한 판단은 SQL Server가 한다)이 있었던 경우 발생하기 때문에 궁극적으로 비주 기적으로 발생된다고 할 수 있다. 다시 말해서 데이터베이스에서 많은 작업이 일어나면 체 크 포인트가 발생하는 주기는 1분이 될 것이며, 데이터베이스에서 일어나는 작업이 많지 않 으면 체크 포인트가 발생하는 주기를 예측할 수 없다는 말이 된다.


# 레이지 라이터 & 로그라이터


 - 레이지 라이터(Lazy Writer)

레이지 라이터(Lazy Writer)라는 프로세스는 메모리 상의 프로시저 캐시에서 시용 빈도가

낮은 실행 계획을 메모리에서 제거하고 버퍼 캐시에 있는 더티 페이지(Dirty Page)들을 디

스크에 기록함으로써 메모리상에 빈 공간을 확보하기 위해서 동작하며, 이 역시 백그라운드

프로세 스로 주기적으로 동작한다.


 - 로그 라이터(Log Writer)라는 프로세스는 트랜잭션이 완료(Commit, 커밋)되면 자동으로

커밋된 트랜잭션에 대한 로그를 트랜잭션 로그 파일에 기록하는 프로세스이다.




### 참조 제약 조건

create table byTbl

(no <-- 숫자 증가값

 name --> uTbl(userid)

 prodname

 groupname

 price

 amount

 ------------------------------------------

  create Table byTbl

(num int Identity Not Null Primary Key,

 userid nchar(8) Not Null 

Foreign Key References uTbl(userid),

 prodName nchar(6) Not Null,

 groupName nchar(4),

 price int Not Null,

 amount smallint Not Null

)

go



### JOIN 사용

-- userTbl,buyTbl에서 하세요


--1) 키가 180 이상인 사람의 userid, 이름, 거주지는?

select userID, name, addr

from userTbl

where height >= 180


--2) 핸드폰 번호가 011,018 인 사람의 userid, 이름, 거주지는?

select userID,name,addr,mobile1

from userTbl

where mobile1 in ('011','018')


--3) 이름이 박주영인 사람의 구매한 목록, 즉

-- 이름,userid, 상품명, 가격, 수량을 구하시요.

select u.name, u.userID, b.prodName, b.price, b.amount

from userTbl u, buyTbl b

where u.userID = b.userid

  and u.name = '박주영'

  

SELECT     userTbl.userID, userTbl.name, buyTbl.prodName, buyTbl.price, buyTbl.amount

FROM         buyTbl INNER JOIN

             userTbl ON buyTbl.userid = userTbl.userID

WHERE     (userTbl.name = N'박주영')


--4) 키가 182 이상인 사람들의 이름,키,userid, 

-- 상품명,가격,수량은?


select u.name, u.height, u.userID, b.prodName, b.price, b.amount

from userTbl u, buyTbl b

where u.userID = b.userid

and u.height >= 182


--5) 키가 182 이상인 사람별 이름, 총구매금액 중 1000이상인

-- 것만 나타내시오

select u.name, sum(b.price*b.amount) as 총구매금액

from userTbl u, buyTbl b

where u.userID = b.userid

and u.height >= 182

group by u.name

having sum(b.price*b.amount) >= 1000


--6) 안정환보다 키가 큰 사람의 이름,birthyear,addr,height ?

--1> 안정환의 키?

select height

from userTbl

where name = '안정환' --> 182

--2> 그 키보다 큰사람의 ~~~~

select name,birthYear,addr,height

from userTbl

where height > 182

--3> 문장 합치기

select name,birthYear,addr,height

from userTbl

where height > (select height

from userTbl

where name = '안정환')

--7) 김남일보다 키가 큰 사람의 이름과 거주지,키

--   구매상품명,가격,수량은?

--1> 김남일의 키는?

select height

from userTbl

where name = '김남일' -- 183

--2> 그 키보다 큰 사람의 ~~~?

select u.name,u.addr,u.height,b.prodName,b.price,b.amount

from userTbl u, buyTbl b

where u.userID = b.userid

and u.height > 183

--3> 문장합치기

select u.name,u.addr,u.height,b.prodName,b.price,b.amount

from userTbl u, buyTbl b

where u.userID = b.userid

and u.height > (select height

from userTbl

where name = '김남일')




### VIEW 설명


 # 뷰(View)


 1) 정의 : Select 문장의 덩어리 

(가상의 논리적 테이블)


 2) 목적 : 편의성, 보안성, 성능향상


 3) 종류 :

- 일반 View

- Index View

- Partition View



drop view v_userTbl


create view v_userTbl

as

 select userid,name,addr from userTbl


select * from v_userTbl 

where name='이천수'


select * from userTbl


update v_userTbl set addr='ZZ' where name = '이천수'

update v_userTbl set height=100 where name = '이천수'


insert into v_userTbl values ('KKK','김금갑','PP')

insert into v_userTbl (userid,name,addr) 

values ('KKK','kkKim','PP')


create View v_userTbl3

 as

 select userid,name,birthyear,addr from userTbl


insert into v_userTbl3 values ('KKK','kkKim','1977','PP')

select * from v_userTbl3


delete v_userTbl3 where userid='KKK'


select * from userTbl


create View v_userTbl4

 as

 select * from userTbl where height >= 180


select * from v_userTbl4


delete v_userTbl4 where height < 180 

select * from userTbl


update v_userTbl4 set birthyear ='1111' 

where height < 180


insert into v_userTbl4 

values ('TTT','ggHong','4444','GG',010,0101,190)

insert into v_userTbl4 

values ('ZZZ','ggHong','4444','GG',010,0101,100)


select * from userTbl


alter view v_userTbl4

as

 select * from userTbl where height >= 180

 with check option



select * from sys.views


Exec sp_helptext 'v_userTbl4'


alter View v_userTbl4

 with Encryption

as

 select * from userTbl where height >= 180

with check option


use sqldb


select * from userTbl --> userTbl2


select * into userTbl2 from userTbl



select * from userTbl2


-- view를 생성 

-- (userid, name, birthyear, addr, height)


create view v_uTbl2

as

select userid,name,birthyear,addr,height

from userTbl2


select * from v_uTbl2


-- userTbl2 에서 height 컬럼을 제거해보세요

alter table usertbl2

drop column height

go


select * from userTbl2


select * from v_uTbl2 <-- 실행되는지요?


drop view v_uTbl3


create view v_uTbl3

with schemabinding

as

select userid,name,birthyear,addr,mobile2

from dbo.userTbl2 --> table명 앞에 dbo 스키마를 선언

go


select * from v_uTbl3


alter table usertbl2

drop column mobile2

go



## SQL Injection


 ID     [  admin' or 1=1 !--  ] 

 PWD    [  1234  ]  


select * from where id ='swhong' or 1=1 



   select * from where id='admin' or 1=1 1!--' and pwd = '1234'


  Exec sp_userid('jane','1234')


 ### 저장프로시저 (Stored Procedure)


 1) 정의 : - Transact-SQL 문장의 집합 


 2) 용도 :

- 어떠한 동작을 절차적 일괄처리 작업하는데 사용

- SQL Server에서 사용하는 프로그래밍 기능


 3) 특징 :

- SQL Server의 성능향상 (첫 실행시 컴파일, 재컴파일 안함)

- 모듈식 프로그래밍 가능

- 보안강화 (저장프로시저 마다의 권한할당 가능)

- 네트워크 전송량 감소 (긴 쿼리문장의 단순화)


 4) 장점 :

- 빠르다

- 파라미터를 사용할 수 있다

- 여러 어플리케이션과 공유할수 있다


------------------------------------------------------------------

 # 일반적인 T SQL 구문 실행절차

1. 첫실행시

 1) 구문분석

 2) 개체검사

 3) 권한확인

 4) 최적화경로확인

 5) 컴파일(with 실행계획) --> 메모리 상주

 6) 실행

2. 두번째실행시 (구문이 같아야)

 1) 기 컴파일 사용

 2) 실행


 # 저장 프로시저

1. 첫실행시

 1) 구문분석

 2) 개체검사

 3) 권한확인

 4) 최적화경로확인

 5) 컴파일(with 실행계획) --> 메모리 상주

 6) 실행

2. 두번째실행시 (구문이 같지않아도)

 1) 기 컴파일 사용

 2) 실행


 use sqldb


create Procedure usp_userTbl

as

 select * from userTbl


Exec usp_userTbl


-- View 일 경우 --

create view v_Test 

as

   select * from userTbl

   

select * from v_Test where userID = 'AJH'


create Proc usp_userTbl2

 @userid nchar(8)

as

 select * from userTbl where userid = @userid

go


Exec usp_userTbl2 'AJH'


create Proc usp_userTbl3

 @a int,

 @b int

as

 select * from userTbl where birthyear > @a and birthyear <= @b

go


Exec usp_userTbl3 1978,1982



create Proc usp_userTbl4

@userid nchar(8)

as

declare @byear int

select @byear = birthyear from userTbl where userid = @userid

if (@byear >= 1978)

Begin

Print 'Low Age'

end

else

Begin

Print 'High Age'

end

go


Exec usp_userTbl4 'AJH'


-- Input Value, Output Value

create Proc usp_userTbl5

@userid nchar(8),

@outAge int OutPut

as

Declare @bYear int

select @bYear = birthyear from userTbl where userid = @userid

select @outAge = Year(getdate()) - @bYear


-- Execute SP

declare @iAge int

Exec usp_userTbl5 'AJH', @iAge Output

Print 'Your Age ==> ' + cast(@iAge as char(5))


select @@NESTLEVEL





### 사용자 정의 함수 (User Defined Function)


 1) 정의 : 리턴값을 갖는 프로시저의 종류


 2) 유형 : 

- 스칼라(Scalar) 함수 

- 테이블 함수

  - 인라인 테이블 값 (Inline Table Valued)함수

  - 다중문 테이블 값 (Multi Statement Table Valued)함수


 3) 제약사항 :

- 함수 내부에 Try Catch 문을 사용할 수 없다

- 함수 내부에 DDL문(Create/Alter/Drop)을 사용할 수 없다


 @ 스칼라 함수: Return문에 의해서 하나의 단일값을 돌려주는 함수

 @ 인라인 테이블값 함수 : Select 문장의 결과 집합을 돌려주는 함수

 @ 다중문 테이블 값 함수 : 정의된 임시 테이블 자체를 돌려주는 함수




 create #tmpTbl (id txt) : 사용할 수 없음



Inline_Fuction.sql


Muti_Fuction.sql


Scalar_Fuction.sql



Posted by redkite
, |

exec sp_help usertbl  -- 테이블 분석

 




## 제약조건(Constraint)

create Table uTbl

(userID nchar(8) Not Null 

Constraint PK_userTbl_userID Primary Key,

 name nvarchar(10) Not Null

Constraint UQ_userTbl_name Unique,

 birthYear int Not Null --> 올해와 이후 100년 사이

Constraint CK_userTbl_BY 

check(birthyear>=year(getdate())

and birthyear<year(dateadd(yy,100,GETDATE()))),

 addr nchar(4) Not Null  --> 기본값 (서울)

Constraint DF_userTbl_addr default('서울'),

 mobile1 nchar(3) --> 010,011,016,017,018,019

Constraint CK_userTbl_mob1

check(mobile1 in ('010','011','016','017','018','019')),

 mobile2 nchar(8),

 height smallint --> 0 ~ 250

Constraint CK_userTbl_height

check (height > 0 and height <= 250)

)

go


select GETDATE()

select YEAR(getdate())

select year(dateadd(yy,100,GETDATE()))

 

 

 

 

SQL Server의 기본 데이터 저장 단위는 페이지입니다. 데이터베이스에서 데이터 파일(.mdf 또는 .ndf)에 할당되는 디스크 공간은 논리적인 페이지로 나뉘어지며 0에서 n 사이의 숫자가 연속으로 페이지에 매겨집니다. 디스크 I/O 작업은 페이지 수준에서 수행됩니다. 즉 SQL Server는 전체 데이터 페이지를 읽거나 씁니다.

익스텐트는 실제로 연속하는 8페이지를 모은 것으로 페이지를 효율적으로 관리하는 데 사용됩니다. 모든 페이지는 익스텐트로 저장됩니다.

SQL Server에서 페이지의 크기는 8KB입니다. 이 사실은 SQL Server 데이터베이스에 메가바이트당 128페이지가 있음을 의미합니다. 각 페이지는 96바이트 머리글로 시작하는데 이 머리글은 페이지에 대한 시스템 정보를 저장하는 데 사용됩니다. 페이지 번호, 페이지 유형, 해당 페이지의 사용 가능한 공간 크기 그리고 해당 페이지를 소유하고 있는 개체의 할당 단위 ID와 같은 정보를 저장합니다.

다음 표에서는 SQL Server 데이터베이스의 데이터 파일에서 사용되는 페이지 유형을 보여 줍니다.

페이지 유형

내용

데이터

text in row가 ON으로 설정된 경우에 text, ntext, image, nvarchar(max), varchar(max), varbinary(max)xml 데이터를 제외한 모든 데이터가 있는 데이터 행

인덱스

인덱스 항목

텍스트/이미지

큰 개체 데이터 형식:

  • text, ntext, image, nvarchar(max), varchar(max), varbinary(max)xml 데이터

데이터 행이 8KB를 초과하는 경우 가변 길이 열:

  • varchar, nvarchar, varbinarysql_variant

전역 할당 맵, 공유 전역 할당 맵

익스텐트가 할당되었는지 여부에 대한 정보

페이지의 사용 가능한 공간

페이지 할당 및 페이지의 사용 가능한 공간에 대한 정보

인덱스 할당 맵

테이블 또는 인덱스에서 할당 단위당 사용하는 익스텐트에 대한 정보

대량 변경 맵

마지막 BACKUP LOG 문 이후에 할당 단위당 대량 작업에 의해 수정된 익스텐트에 대한 정보

차등 변경 맵

마지막 BACKUP DATABASE 문 이후에 할당 단위당 변경된 익스텐트에 대한 정보

참고참고

로그 파일은 페이지는 포함하지 않으며 일련의 로그 레코드를 포함합니다.

데이터 행은 머리글 바로 다음부터 시작하여 페이지에 차례로 나옵니다. 행 오프셋 테이블은 페이지 끝에서 시작하는데 각 행 오프셋 테이블에는 해당 페이지에 있는 각 행에 대한 항목이 하나씩 있습니다. 각 항목은 해당 행의 첫째 바이트가 페이지 시작 지점에서 얼마나 떨어져 있는지를 기록합니다. 행 오프셋 테이블의 항목 순서는 페이지의 행 순서의 역순입니다.

행 오프셋이 있는 SQL Server 데이터 페이지

대용량 행 지원

행들이 여러 페이지에 걸쳐 있을 수 없지만 그러한 행 부분들이 해당 행의 페이지를 벗어나서 해당 행이 실제로는 아주 커질 수 있습니다. 한 페이지의 단일 행에 데이터와 오버헤드가 최대 8,060바이트(8KB)까지 저장됩니다. 그러나 텍스트/이미지 페이지 유형에 저장되는 데이터는 여기에 포함되지 않습니다. varchar, nvarchar, varbinary 또는 sql_variant 열이 있는 테이블의 경우 이러한 제한이 완화됩니다. 테이블에 있는 모든 고정 및 변수 열의 전체 행 크기가 8,060바이트 한계를 초과하면 SQL Server는 하나 이상의 가변 길이 열을 가장 너비가 넓은 열부터 시작하여 ROW_OVERFLOW_DATA 할당 단위에 있는 페이지로 동적으로 옮깁니다. 삽입 또는 업데이트 작업으로 행의 전체 크기가 8060바이트 한계를 초과하면 이러한 작업이 수행됩니다. 열이 ROW_OVERFLOW_DATA 할당 단위의 페이지로 이동하면 IN_ROW_DATA 할당 단위에 있는 원래 페이지의 24바이트 포인터가 그대로 유지됩니다. 후속 작업으로 행 크기가 줄면 SQL Server가 동적으로 열을 다시 원래 데이터 페이지로 이동합니다. 자세한 내용은 8KB를 초과하는 행 오버플로 데이터를 참조하십시오.

익스텐트는 공간 관리의 기본 단위입니다. 하나의 익스텐트는 실제로 연속하는 8페이지 또는 64KB입니다. 이 사실은 SQL Server 데이터베이스에 메가바이트당 익스텐트가 16개 있음을 의미합니다.

SQL Server은 효율적인 공간 할당을 위해 적은 양의 데이터를 포함하는 테이블에 전체 익스텐트를 할당하지 않습니다. SQL Server에는 다음 두 가지 유형의 익스텐트가 있습니다.

  • 균일 익스텐트는 단일 개체가 소유합니다. 또한 익스텐트의 전체 8페이지는 소유하는 개체만 사용할 수 있습니다.

  • 혼합 익스텐트는 최대 8개의 개체가 공유할 수 있습니다. 익스텐트의 8페이지를 각각 다른 개체가 소유할 수 있습니다.

일반적으로 새 테이블이나 인덱스에는 혼합 익스텐트의 페이지가 할당됩니다. 테이블이나 인덱스의 페이지가 8페이지로 증가하면 후속 할당을 위해 균일 익스텐트를 사용하도록 전환됩니다. 인덱스에 8개의 페이지를 생성하는 데 충분한 행을 가진 기존 테이블에서 인덱스를 만드는 경우 인덱스에 대한 모든 할당 항목은 균일 익스텐트에 있습니다.

혼합 및 단일 익스텐트


 

 

### SHRINK 테스트

@@@ shrink database @@@

use master
create database shrinkDB
on Primary
(name = shrinkDB,
 Filename = N'C:\database\sDB\shrinkDb.mdf',
 size=3MB)
Log on
(name = shrinkDB_Log,
 Filename= N'C:\database\sDB\shrinkDb_log.ldf',
 size=3MB)

-- 1 (insert A) --

use shrinkDB
create Table test (txt varchar(1024))
go

Declare @i int
set @i = 0
while @i < 1024*10
Begin
 insert into test values (replicate ('A', 1024)) 
 set @i = @i+1
end

-- 2 (insert B,C) --

Declare @i int
set @i = 0
while @i < 1024*10
Begin
 insert into test values (replicate ('B', 1024)) 
 set @i = @i+1
end

set @i = 0
while @i < 1024*10
Begin
 insert into test values (replicate ('C', 1024)) 
 set @i = @i+1
end

-- 3 (shrink database [SSMS])

-- 4 (view Size)

-- 5 (delete B)
delete test where substring(txt,1,1) = 'B'

-- 6 (shrink database [SSMS])

-- 7 (view Size)



### File Group


 - Database Object에 대한 저장

 - Data File의 묶음

 - Raid 0 구성 (I/O를 향상) 

   -> 물리적 드라이브가 실제 분리되어 있어야 효과

 - 주 Data File(.mdf)은 기본적으로

   -> Primary File Group 소속되어져 있음

 - Primary File Group은 읽기 전용 그룹이 될 수 없음


 - 나머지 File Group은 읽기 전용 그룹이 될 수 있음


 - 백업/복원의 대상이 됨


 - 증분복원: 단계적 복원이 가능


 

Posted by redkite
, |

# Table 이란??

 - Data가 저장되어지는 논리적 구조의 객체(그릇)
 - 행(Record)과 열(Column)이 존재
 - Table in RDB(관계형DB)에서는 자기/다른 Table
 과의 관계(Relationship)설정이 가능

 -> 일관성, 무결성을 위한 모델링을 하게되면

    분리된 Table 사이에서 연결고리를

    찾는게 어려워 지기때문에

    그것을 관계를 통해 해결

 - 모델링, 정규화 --> 데이터의 무결성


 # E-R 관계 사상 알고리즘

 - 단계 1: 정규 엔티티  <= 테이블 + 기본키
 - 단계 2: 약한 엔티티  <= 부모의 키 + 부분키
 - 단계 3: 1:1 관계타입  <= 부모의 PK -> 자식의 PK,FK
 - 단계 4: 1:N 관계타입  <= 부모의 PK -> 자식의 FK
 - 단계 5: M:N 관계타입  <= 신규테이블 + [양측의 PK -> FK]
 - 단계 6: 다치 애트리뷰트  <= 신규테이블 + [부모의 PK -> FK]

 

 

# 정규화란 중복성을 최소화하고 정보의 일관성을 보장하기 위한 관계형 데이터 베이스에서 제일 중요한 개념.


# 정규화를 하는 이유

 - 데이터의 중복성 제거
 - 데이터 모형의 단순화
 - Entity,Attribut의 누락여부
 - 데이터모형의 안전성 검증

 

 

 

 # Data 무결성

 1) 참조무결성 : 테이블간 불일치 데이터 방지하자
 2) 실체무결성 : 기본키로 Row를 구분하자
 3) 도메인무결성: 잘못된 형식을 방지하자

 # 정규화
 
 1) 1정규형
 - 데이터의 중복제거
 - 컬럼의 중복제거

 2) 2정규형
 - 기본키 전체에 의존 컬럼분류

 3) 3정규형
 - 일반컬럼 의존적 컬럼 분리


 

# 제 1정규화

 - 엔티티 내의 모든 속성은 반드시 하나의 값을 가져야 한다.

 - 여러 값을 가진 컬럼이 존재할 수 없다. 즉 반복되는 그룹이 존재해서는 안 된다. 각 행과 열에는 하나의 값만이 올수 있다.

# 제 2정규화

 - 복합키를 식별자로 가지는 경우 복합키의 일부분에만 종속적인 항목을 분류하는 작업

 - 모든키가 아닌 컬럼은 기본 키 전체에 의존적이여야 한다. 기본키의 일부분에 의존적이어서는 안 된다.

# 제3정규화
 
 - 엔티티 내의 식별자를 제외한 모든 속성은 종속될 수 없다.

 - 키가아닌 컬럼은, 다른 키가 아닌 컬럼에 의존적일어서는 안된다.

# 역정규화

 - 데이터의 중복을 통해 과도한 논리적 결합현상을 피한다.
 
 - 유도된 컬럼을 추가하여 불필요한 연산을 피한다. (예)판매금액=수량*단가

 - 하나의 테이블을 2개 이상의 테이블로 분리하여 불필요한 컬럼의 검색을 피한다.

 - 자주 사용되는 테이블의 논리적 결합을 피하기 위해 집계테이블을 생성한다.

논리적 모델링 단계에서 논해야 하는 문제는 개념적 모델링 후,

매핑룰에 의해 기초적인 논리적 모델링으로 내려 오고

논리적 모델링시에는 흔히 이야기 하는 정규화 과정을 거치게 됩니다.

즉, 차수 정의(1:1, 1:M, N:M)관계는 이미 개념적 모델링에서 처리가 된다는 것입니다.

 DA# 프로그램으로 말하면 플래너 단계에서 이루어 진다고 봅니다.

이에 대한 논리적 모델링 단계에선 관계형 데이타 베이스에 맞는 모델링을 해야 합니다.

마지막 단계에서 역정규화 작업이나.. 여타 작업을 하지만,

이것이 테이블에 대한 분리를 이야기 하지 않습니다.

정규화 단계를 많은 사람들이 알고 있듯이 테이블의 분할이라는 것은

속성에 대한 재정의 (차수의 변경등에 의한)를

통해서 속성에 대한 테이블의 분리로 이루어 질 수 있습니다.

하지만, 논리적 모델링 단계에서는 DBMS의 벤더에 종속되지 않는 모델링이 이루어 져야 하고,

 관계형 데이터베이스의 이론에 충실한 모델링이 이루어 져야 합니다.

1:1 엔티티에 대한 내용은 역정규화시에 통합이 되어야 하고, 업무분석시에 이루어지는 검색조건이나, 여타 조건에 의한 테이블의 분할이라는 것은 DBMS가 정해지고 플랫폼의 정의가 이루어진 후, 물리적 모델링 단계에서 이루어 져야 한다고 봅니다.
저는 1:1 엔티티에 대한 통합은 논리적 모델링 관계에서 무조건적으로 통합되어야 한다고 봅니다.

 

####

BCNF 정규화는
3정규형에서 BCNF 정규형이 되려면 비결정자에의한 함수종속을 제거해야 하는것을 알고계시죠..
비결정자에 의한 함수종속을 제거해서 분해된 BCNF정규형은
결과적으로 모든 속성들이 후보키로서 사용이 가능한 형태로 분해됩니다.
다시 말해 분해된 테이블의 모든 결정자들이 후보키이면
BCNF정규형이라 말합니다
제4정규화는
2정규화 된 테이블은 다대다 관계를 가질수 없다.
이건 따로 예를 안들어도 되겠죠?ㅋㅋ

 

 

#### 제약조건

 

 1. PK  : 기본키 => 유일한값 , NULL(X), Index (기본값:CI)

 2. UQ  : 유니크 => 유일한값 , NULL(1[MS]), Index (기본값:NCI)
          NULL(다[Ora])

 3. FK : 외래키 => 자기/다른 테이블의 PK, UQ를 참조

  참조하는 컬럼의 DataType과 Size가 일치

 4. CK : 범위 설정 => 0 < 값 < 100
   열거 조건 => 값 in (값1, 값2, 값3,,,,)

 5. DF : 기본값

 6. NN : Not Null => Null 값 허용 여부

 

 

Posted by redkite
, |

 

 

 

 

 

# Application

  - Database Server : MS SQL Server

    - Database Engine
# - DBMS (SSMS[DB Obejct / Query]
  SSCM[Service / Network])

#     -  Instance <-- IP (외부접속 연결대상)
 
         1차 이름      2차 이름
   ------------------------------
  * 외부 이름 : HostName    HostName\Test
  * 내부 이름 : MSSQLSERVER    Test

      --> 접속 연결 이름

   로컬 : .   or localhost
   내부 : MSSQLSERVER
   외부 : hosname or IP

      --> DB Engine Service 실행 OS Account

   - Administrator : OS 전체 관리 계정(사용자환경)
   - 일반 OS User  : 일반 사용자 계정
   - Local System  : OS 전체 관리 계정(컴퓨터환경)
   - Local Service : 일반 서비스 계정


      --> Instance 구성정보

  - System Database
     1) master : Instance 전체 구성정보
     2) model  : Database의 기본 틀 제공
     3) msdb   : 운영 업무 자동화의 관련 정보
     4) tempdb : 임시 Database (휘발성)


 
#  - Database : 업무에 따른 공간

#     - Schema : 사전 정의

#   - Object : Table

 

 

# SQL Server  관리 도구

 - SSMS : 개체관리 + 쿼리분석
 - SSCM : 서비스 + 네트워크 설정
 - SQL cmd : DOS 창에서 사용하는 SQL 명령어 도구

 

### 작업 스크립트

 

01. identity.sql

02. UNIQUEIDENTIFIER 데이터 형식.sql

03. HIERARCHYID.sql

04. Date 데이터형식.sql

05. char_varchar.sql

06. Collation.sql

07. null저장공간.sql

08. smallDateTime.sql

09. Time.sql

10. XML_DataConversion.sql

# SQL CMD 명령어

 - sqlcmd /?

C:\Users\Administrator>sqlcmd
1> use testdb
2> go
데이터베이스 컨텍스트가 'testDB'(으)로 변경되었습니다.
1> select * from t1;
2> go
id
-----------

(0개 행 적용됨)
1> insert into t1 values(10)                                                                     ==>  SQL 표준 문법
2> go

(1개 행 적용됨)
1> insert into t1 values(20)
2> insert into t1 values(30)
3> insert into t1 values(40)
4> go

(1개 행 적용됨)

1> insert into t1 values(50),(60),(70)                                                        ==> SQL 서버에서만 사용가능한 문법
2> go

(3개 행 적용됨)
1> select * from T1
2> go
id
-----------
         10
         20
         30
         40
         50
         60
         70

(7개 행 적용됨)

 

#  데이터 값 사용에 대한 확인

 

null저장공간.sql

 

 

 

### XML 데이터 타입으로 변경

 

CreateSampleTbl.sql

 

InsertBuyTbl.sql

 

InsertUserTbl.sql

select * from userTbl
where height > 180
for xml raw('열')

 

- 트리 구조로 변경

  

 

- xml 데이터 값으로 출력

 

- xml db 형태로 변환

 

 

 

 

'01.MS-SQL' 카테고리의 다른 글

[MSSQL]MS-SQL 2일차 - Object 관리  (0) 2013.04.02
[MSSQL]MS-SQL 1일차 - 테이블 / 정규화  (0) 2013.04.01
[MSSQL]MS-SQL 설치  (0) 2013.04.01
[MSSQL]데이터베이스 이동  (0) 2012.12.19
[MSSQL]Windows 64Bit And MS-SQL 32Bit  (0) 2012.12.19
Posted by redkite
, |

[MSSQL]MS-SQL 설치

01.MS-SQL / 2013. 4. 1. 11:49

1. 설치 패키지

 

 

2. 설치 전 최종 단계

 

Posted by redkite
, |

ALTER DATABASE 재배치 프로시저를 사용하여 사용자 데이터베이스를 이동하는 방법을 정리하였습니다.

일반적으로 동일한 SQL Server 인스턴스 내에서 파일 이동이 필요할 경우에 이 방법을 사용하며, 만약 다른 인스턴스나  다른 SQL Server로 이동한다면 분리 및 연결(sp_attach_db, sp_detach_db 시스템 저장 프로시져) 방법 또는 백업 및 복원 방법을 이용하면 됩니다.


[시나리오]
1. 데이터베이스명 : LAIGO

2. 변경 전 파일 경로
   1) C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\LAIGO.mdf
   2) C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\LAIGO_log.ldf

3. 변경 후 파일 경로
   1) D:\Data\laigo.mdf  
   2) D:\Data\laigo_log.ldf


[작업절차]


USE MASTER
GO

-- 1. 파일의 논리 이름을 확인합니다.
SELECT file_id, name, physical_name  FROM sys.master_files WHERE database_id = db_id('LAIGO');
/* LAIGO, LAIGO_LOG */


-- 2. 30초 후 모든 작업을 롤백하고 단일 사용자 모드로 전환합니다.
ALTER DATABASE LAIGO SET SINGLE_USER WITH ROLLBACK AFTER 30

** 에러 발생 시 세션 KILL 후에 3번 스탭 진행
select d.name, d.dbid, spid, login_time, nt_domain, nt_username, loginame   from sysprocesses p inner join sysdatabases d on p.dbid = d.dbid where d.name = 'MonitoringDB'
go 
kill 51 --spid
go

-- 3. LAIGO 데이터베이스 오프라인 상태로 전환합니다.
ALTER DATABASE LAIGO SET OFFLINE

ALTER DATABASE MonitoringDB SET OFFLINE


-- 4. mdf,ldf 파일 위치를 변경합니다.


-- 5. mdf 파일 위치 정보를 변경합니다.
ALTER DATABASE LAIGO MODIFY FILE (NAME=LAIGO, FILENAME='d:\data\laigo.mdf')

ALTER DATABASE MonitoringDB MODIFY FILE (NAME=MonitoringDB, FILENAME='d:\SQLDATA\MonitoringDB.mdf')


-- 6. ldf 파일 위치 정보를 변경합니다.
ALTER DATABASE LAIGO MODIFY FILE (NAME=LAIGO_LOG, FILENAME='d:\data\laigo_log.ldf')


ALTER DATABASE MonitoringDB MODIFY FILE (NAME=MonitoringDB_log, FILENAME='d:\SQLDATA\MonitoringDB_log.ldf')


-- 7. 데이버테이스를 온라인 상태로 전환합니다.
ALTER DATABASE LAIGO SET ONLINE

ALTER DATABASE MonitoringDB SET ONLINE 


--8. 멀티 사용자 모드로 변경합니다.
ALTER DATABASE LAIGO SET MULTI_USER

ALTER DATABASE MonitoringDB SET MULTI_USER


-- 9. 정상적으로 변경되었는지 확인합니다.
SELECT  name, physical_name  AS CurrentLocation, state_desc  FROM  sys.master_files
WHERE  database_id  = DB_ID(N'LAIGO');





[참고자료]
사용자 데이터베이스 이동
http://msdn.microsoft.com/ko-kr/library/ms345483.aspx

방법: 분리 및 연결을 사용하여 데이터베이스 이동(Transact-SQL)
http://msdn.microsoft.com/ko-kr/library/ms187858.aspx

시스템 데이터베이스 이동
http://technet.microsoft.com/ko-kr/library/ms345408.aspx

 

'01.MS-SQL' 카테고리의 다른 글

[MSSQL]MS-SQL 1일차 - 기본 사용법 + 개념 교육  (0) 2013.04.01
[MSSQL]MS-SQL 설치  (0) 2013.04.01
[MSSQL]Windows 64Bit And MS-SQL 32Bit  (0) 2012.12.19
[MSSQL]Transaction Kill  (0) 2012.12.19
[MSSQL]데이터 파일 축소  (0) 2012.12.19
Posted by redkite
, |

Configuring IIS to Run 32-bit ASP.NET Applications on 64-bit Windows

3 out of 6 rated this helpful - Rate this topic

Updated: August 22, 2005

Applies To: Windows Server 2003, Windows Server 2003 R2, Windows Server 2003 with SP1

If you intend to run 32-bit ASP.NET applications on 64-bit Windows, you must configure IIS to create 32-bit worker processes. For more information about running 32-bit applications on 64-bit Windows, see Running 32-bit Applications on 64-bit Windows.

IIS cannot run 32-bit and 64-bit applications concurrently on the same server.

To enable IIS 6.0 to run 32-bit ASP.NET applications on 64-bit Windows
  1. Open a command prompt and navigate to the %systemdrive%\Inetpub\AdminScripts directory.

  2. Type the following command:

    cscript.exe adsutil.vbs set W3SVC/AppPools/Enable32BitAppOnWin64 true

  3. Press ENTER.

  4. Download and install the Microsoft .NET Framework Version 1.1 Redistributable Package.

'01.MS-SQL' 카테고리의 다른 글

[MSSQL]MS-SQL 설치  (0) 2013.04.01
[MSSQL]데이터베이스 이동  (0) 2012.12.19
[MSSQL]Transaction Kill  (0) 2012.12.19
[MSSQL]데이터 파일 축소  (0) 2012.12.19
[MSSQL]DateTime 변환 함수  (0) 2012.12.19
Posted by redkite
, |

[MSSQL]Transaction Kill

01.MS-SQL / 2012. 12. 19. 16:29

Transact-SQL KILL 명령은 SQL Server 프로세스를 갑자기 끝낼 때 사용됩니다. 각 프로세스를 시스템 프로세스 ID(spid)

Transact-SQL KILL 명령은 SQL Server 프로세스를 갑자기 끝낼 때 사용됩니다. 각 프로세스를 시스템 프로세스 ID(spid)라고도 합니다. SQL Enterprise Manager(엔터프라이즈 관리자)의 Current Activity 아래에 있는 Kill Process 단추는 단지 Transact-SQL KILL 명령을 서버로 보내는것으로(낼뿐므로) 이 경우 서버쪽 KILL 메커니즘과() 동일하게 작동합니다.

spid는 KILL 명령에 즉시 응답(하거나), 지연 후 응답(하거나), 또는 전혀 응답하지 않는 경우가 있습니다.(않습니다). 어떤 조건에서는 KILL 명령에대해 지연 후 응답하거나 또는 전혀 응답하지 않는 것이 정상일 수 있습니다. 본 문서에서는 이러한 KILL 명령의 작동 방법과 KILL명령수행이 지연되는 및 ()수행되지()않는 조건( 그러한 조건)을 식별하는 방법에 대해(을) 설명합니다.

 

데이터베이스 연결은 spid 또는 시스템 프로세스 ID를 가지는 행을 (라고도 하며) sysprocesses에 삽입하므로써() 형성됩니다.

각 데이터베이스 연결은 spid 또는 시스템 프로세스 ID를 가지는 행을 (라고도 하며) sysprocesses에 삽입하므로써() 형성됩니다.(합니다). 이러한(각) 연결을 SQL Server 용어로 "프로세스"라고도 하지만 이는 일반적인 관점에서 말하는 개별적인 프로세스 는것은() 아닙니다(않습니다). SQL Server 6.0과 6.5에서 각 프로세스는 개별적인 운영 체제 스레드(Thread)와 거의 유사하며 그러한 개별 스레드가 각 프로세스의 작업을 담당합니다. 또한, 각 데이터베이스 연결은 프로세스 상태, 트랜잭션 상태, 보유한 잠금(Lock) 등을 추적하는 서버 데이터 구조들로 구성됩니다. 이러한 구조 중 하나가 프로세스 상태 구조(PSS)로서, PSS는 각 연결마다 하나씩 있습니다. 서버는 PSS의 목록을 검색하여 sysprocesses 가상 테이블을 구체화합니다. 따라서, sysprocesses의 CPU 및 physical_io 열(Column)은 각 PSS에 있는 동등한 값으로부터 파생된것입니다.(됩니다.)

Transact-SQL KILL 명령은 spid의 프로세스 슬롯 구조(Process Slot Structure)에 "스스로 중지(Kill Yourself)"하라는 메시지를 보냅니다. 이 메시지는 spid가 주기적으로 검사하는 상태 비트로 표현됩니다.(나타납니다.) spid가 PSS 상태 필드를 검사하지 않는 코드 경로를 실행 중이면 KILL 명령은(이) 이행되지 않습니다. 이러한 상황이 발생할 수 있는 것으로 알려진 몇 가지 조건을 아래에서 설명합니다. 따라서, 이들 조건 대부분은 버그가 아니라 예상된 동작으로 간주됩니다.

 

Spid가 네트워크 입출력(Network I/O)을 기다리는 경우

클라이언트가 모든 결과 값(행)을 서버로부터 가져오지 못하면 결국 서버는 클라이언트가 결과값을 가져와서(에) 쓰는 동안습니다. 이 상황은 sysprocesses.waittype 0x0800으로 나타납니다. 네트워크를 기다리는 동안은 어떤 SQL Server 코드도 PSS를 검사하고 KILL 명령을 검색할 수 없습니다.(있는 SQL Server 코드가 실행되지 않습니다.) 네트워크 입출력을 기다리기 전에 spid가(에) 잠금(Lock)에(이) 걸려 있으면 이는 다른 프로세스를(가) 차단시킬수(될 수도) 있습니다.

네트워크 연결이 시간을 초과하거나 수동으로 취소되면 네트워크 입출력을 기다리는 SQL 스레드(Thread)는 오류 반환을 수신하고 그러므로써(그럼으로써) 대기 상태에서 해제되어 PSS를 검사하고 KILL 명령에 응답할 수 있게 됩니다. NET SESSION, NET FILES 명령이나 동일한 기능의 서버 관리자 명령을 사용하여 (수동으로) 명명된 파이프(Named Pipe) 연결을 수동으로 닫을 수 있습니다. TCP/IP와 SPX/IPX 같은 다른 IPC 세션은 수동으로 닫을 수 없으므로, 이 경우에 사용할 수 있는 유일한 방법은 특정 IPC에 대한 세션 시간 제한을 더 작은 값으로 조정하는 것 뿐입니다. 자세한 내용은 Microsoft 기술 자료의 다음 문서를 참조하십시오.

 

137983  (http://support.microsoft.com/kb/137983/EN-US/ ) : How to Troubleshoot Orphaned Connections in SQL Server

 

Spid가 롤백(Roll Back) 또는 취소(Backout) 중인 경우

어떤 이유로든 트랜잭션이 중지되면 그 트랜잭션은 롤백(Roll Back)되어야 합니다. 오랫 동안 실행하는 트랜잭션이 중지된 경우에는 트랜잭션이 적용된 만큼(을 적용하는 것만큼) 롤백(Roll Back)하는데 시간이 오래 걸릴 수 있습니다. 이러한(그러한) 트랜잭션으로는 단일 SELECT INTO, DELETE 또는 UPDATE 문과 같이(은) 오랫 동안 실행한(하는) 암시적 트랜잭션이 있습니다. 롤백(Roll Back)하는 동안은 트랜잭션을 중지할 수 없습니다. 그렇지 않으면 트랜잭션 가능한 변경 내용을 일관성 있게 취소(Backout)할 수 없기 때문입니다.

(sp_who 출력에 ROLLBACK 명령이 나타날 수도 있으므로) 종종 sp_who 출력을 관찰함으로써 중지 불가능한 롤백(Roll Back) 상황을 확인할수 있는데 이는 sp_who 수행결과에서 ROLLBACK명령으로 나타날수 있습니다.(있습니다.) SQL Server 버전 6.5 서비스 팩 2 이상에는 sysprocesses.status에 ROLLBACK 상태가 추가되었습니다. 이 상태는 sp_who 출력이나 SQL 엔터프라이즈 관리자의 "현재 동작(Current Activity)" 화면에도 나타납니다. 그러나, 이 정보를 얻는 가장 신뢰할 만한(수 있는) 방법은 문제가 있는 차단 SPID의 DBCC PSS를 조사하고 pstat 값을 관찰하는 것입니다. 아래에 예가 있습니다.

 

dbcc traceon(3604) /* Return subsequent DBCC output to the client rather    
than to the errorlog. */
go
SELECT SUID FROM SYSPROCESSES WHERE SPID=<unkillable SPID number>
go
DBCC PSS (suid, spid, 0) /* Where suid is from above, and spid is the
                            unkillable SPID number. */
go

 

반환된 정보에서 첫째 줄은 pstat 값을 포함합니다.

예를 들어, pstat 값은 아래와 같습니다.

 

pstat=0x4000, 0x800, 0x100, 0x1

pstat 비트의 의미는 아래와 같습니다.

0x4000 -- 중요 섹션 안에 있으면 KILL 및 ATTENTION 신호를 지연시킵니다.
0x2000 -- 프로세스가 중지되고 있습니다(됩니다.)
0x800  -- 프로세스가 취소(Backout) 중이기 때문에 교착 상태 프로세스로 선택될 수 없습니다.
0x400  -- 프로세스가 ATTENTION 신호를 수신했고 내부 예외를
          발생하여 응답했습니다.
0x100  -- 프로세스가 단일 문 트랜잭션의 중간에 있습니다.
0x80   -- 프로세스가 분산(다중) 데이터베이스 트랜잭션과 관계됩니다.
0x8    -- 프로세스가 현재 트리거(Trigger)를 수행 중입니다.
0x2    -- 프로세스가 KILL 명령을 수신했습니다.
0x1    -- 프로세스가 ATTENTION 신호를 수신했습니다.

 

GUI 응용 프로그램에서 쿼리 취소 단추를 누르는 등의 취소 동작에 의해 오랫 동안 실행하는 데이터 수정 프로세스가 취소되고(된 다음) 해당 spid가 잠시 동안 사용자를 차단하는(여전히 중지할 수 없는)것으로 ( SPID가) 발견되었을 경우, 일반적으로 위와 같은 pstat 값이 나타납니다. 이 상황은 정상이며 트랜잭션은 취소(Backout)되어야 합니다. 위에 나와 있듯이 비트에서 이를 확인할 수 있습니다.

 

Spid 1이 상태 0000(복구 실행 중)을 가지는 경우

SQL Server를 시작하거나 재시작할 때 각 데이터베이스는(를) 사용되(하)기 전에 시작 복구가(를) 완료되어져야(해야) 합니다. 이러한 복구 진행상황은(이것은) sp_who에 있는(서) 첫번째 spid의 상태값이 0000을 가지는것으로 알수 있습니다.(나타납니다). 이 spid는 중지될 수 없으며 복구 프로세스는 서버를 다시 시작하지 않고도 완료할 때까지 실행될 수 있어야 합니다. lazywriter, 검사점(Checkpoint), RA Manager 같은 시스템 spid는 중지할 수 없고 사용자 spid만 중지할 수 있습니다. 또한 자신이 소유한 spid도 중지할 수 없습니다. SELECT @@SPID를 사용하면 자신의 spid를 알 수 있습니다.

 

서버가 KILL 이행을 고의로 지연시킨 경우

문 경우지만 서버가 고의로 KILL 명령이나 ATTENTION 신호(쿼리 취소 요청)에 대한 조치를 지연시킬 수도 있습니다. 이러한 상황의 예는 중요 섹션에 있는 동안입니다. 이 간격은 대개 짧습니다. 이 상황은 pstat 값 0x4000으로 알 수 있습니다.

 

코드 경로가 KILL을 확인하지 않는 경우

위의 각 시나리오 중 어느 것에도 해당하지 않는다면 단순히 현재 코드 경로가 KILL을 확인하지 않는 경우일 수 있습니다. 예를 들어, SQL Server 버전 6.5 서비스 팩 3 이전에는 특정 코드 경로가 KILL을 확인하지 않았기 때문에 DBCC CHECKDB는(가) KILL 명령에 대해 신뢰성 있게 응답하지 않았습니다. 위의 모든 경우(즉, 사용자 프로세스가 입출력을 기다리거나 또는 롤백(Roll Back) 중이거나, 데이터베이스가 복구 중이거나 SQL Server가 고의로 KILL을 지연시키는 경우)에 해당하지 않지만 여전히 KILL 명령이 이행되지 않으면, KILL이 작동하도록 서버를 향상하는 것이 좋습니다. 이를 확인하려면 주 지원 공급자에게 각 경우를 개별적으로 검사하게 해야 합니다.

 

기타 정보

"호스트 이름 JOE가 프로세스 id 10을 중지했습니다."라는 메시지가 오류 로그에 기록되었다는 사실만으로 KILL이 실제로 이행되었다고 확신할 수는 없습니다. 이 메시지는 중지 요청을 보낸 직후 기록되므로 KILL이 실제로 이행되었음을 나타내는 것은 아닙니다.

 

'01.MS-SQL' 카테고리의 다른 글

[MSSQL]데이터베이스 이동  (0) 2012.12.19
[MSSQL]Windows 64Bit And MS-SQL 32Bit  (0) 2012.12.19
[MSSQL]데이터 파일 축소  (0) 2012.12.19
[MSSQL]DateTime 변환 함수  (0) 2012.12.19
[MSSQL]테이블별 용량 확인  (0) 2012.12.19
Posted by redkite
, |

SQL Server 2005 에서 데이터(mdf,ndf) 파일을 축소하는 방법에 대해서 아래와 같이 정리하였습니다.

데이터 파일의 할당 정보는 DBCC SHOWFILESTATS 명령을 사용하여 확인할 수 있습니다. 트 랜잭션 로그 파일의 현재 사용 가능한 빈공간을 조회할 때 DBCC SQLPERF(LOGSPACE) 명령을 사용하면 됩니다.


USE LAIGO

GO

DBCC SHOWFILESTATS



아래와 같이 LAIGO 데이터베이스의 데이터 파일 LAIGO 의 전체 크기와 사용량을 확인할 수 있습니다.

Fileid FileGroup TotalExtents UsedExtents Name FileName

--------------------------------------------------------------------------------------------------------------

1 1 880 92 LAIGO D:\LAIGO.mdf


(1개 행 적용됨)



자, 산수시간입니다.

SQL Server 의 기본 저장 단위 Page 의 크기는 8KB, 이며 8개의 연속 페이지로 크기가 고정된 Extent 로 저장됩니다.

1MB = 1024KB = 128(1024/8) Page = 16(1024/64) Extents


TotalExtents 값이 880 Extents 면, 1MB가 16 Extents 이므로 880/16 = 55 MB 가 됩니다.

UsedExtents 값이 92 면, 92/16 = 5.75 MB 가 됩니다.


즉, 현재 할당된 데이터 파일의 크기는 55MB 입니다만 실제 사용량은 5.75MB 라는 것을 알 수 있습니다.


불필요한 공간을 줄이기 위해 데이터 파일을 축소하는 방법은 아래와 같습니다. LAIGO 파일의 크기를 10MB 로 축소하라는 의미입니다. 실제 TotalExtents 가 160 즉, 10MB 로 줄었습니다.


DBCC SHRINKFILE (LAIGO, 10)


Fileid FileGroup TotalExtents UsedExtents Name FileName

--------------------------------------------------------------------------------------------------------------

1 1 160 92 LAIGO D:\LAIGO.mdf


(1개 행 적용됨)



TRUNCATEONLY 를 사용해 보면 어떨까요?


DBCC SHRINKFILE (LAIGO, TRUNCATEONLY)

DBCC SHOWFILESTATS


아직 사용되지 않은 뒷부분 빈공간이 싹뚝 잘려 나갔습니다.

Fileid FileGroup TotalExtents UsedExtents Name FileName

--------------------------------------------------------------------------------------------------------------

1 1 92 92 LAIGO D:\LAIGO.mdf


(1개 행 적용됨)


Single user 모드가 아니어도 작업은 가능합니다만 가능하면 Single User 모드가 아닌 상태에서 Deadlock 이 발생하는 사례가 있으므로 급한 상황이 아니라면 Single user 모드에서 작업하는 게 좋을 것 같다는 의견입니다. 만약 작업이 실패할 경우에는 SQL Error Log 을 살펴봐야 할 것 같습니다.

ALTER DATABASE LAIGO SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO


DBCC SHRINKFILE(LAIGO_DATA1, 3000) -- 3GB


ALTER DATABASE LAIGO SET MULTI_USER
GO


 데이터파일 축소 실습

실제 사용하는 databae의 크기보다, db파일(mdf, ldf) 사이즈가 클 경우, dbcc shrinkfile

쿼리문을 통해, 사이즈를 줄이는 방법에 대해 포스팅 하도록 하겠습니다.

참고로, 공간 부족으로 인한 장애발생을 대비하기 위해, databae파일과 로그파일 위치 및 size는

check 하셔야 합니다.

   

1. jkmoon 데이터베이스를 생성, test테이블을 만들어 데이터베이스의 사이즈를

1GB로 늘렸습니다. 그런 다음 사이즈가 큰 test 테이블을 삭제하였습니다.

   

2. jkmoon 데이터베이스 파일과 로그파일을 확인 하였습니다.

   

3. 로그사이즈를 먼저 확인하도록 합니다. 1.3GB중에서 약 1.7% 사용 중입니다.

dbcc sqlperf (logspace);

   

4. jkmoon 데이터베이스 파일, 로그의 이름과 위치를 확인 합니다.

Sp_helpdb jkmoon;

   

5. 쿼리문을 수행하여, 10MB로 로그파일을 줄입니다.

Use jkmoon

Go

   

dbcc shrinkfile (jkmoon_log, 10);

   

Jkmoon_log.ldf 로그사이즈가 줄어든걸 확인 하였습니다.

   

6. 마찬가지로, database파일도 사이즈를 10MB로 줄입니다.

Use jkmoon

go

   

Dbcc shrinkfile (jkmoon, 10);

   

 

'01.MS-SQL' 카테고리의 다른 글

[MSSQL]Windows 64Bit And MS-SQL 32Bit  (0) 2012.12.19
[MSSQL]Transaction Kill  (0) 2012.12.19
[MSSQL]DateTime 변환 함수  (0) 2012.12.19
[MSSQL]테이블별 용량 확인  (0) 2012.12.19
[MSSQL]자주 사용하는 명령어  (0) 2012.12.19
Posted by redkite
, |

1.     문자 식에서 가장 왼쪽 문자의 ASCII 코드 값 반환 (숫자로 표시됨)


구분

MSSQL

Oracle

함수

ASCII

ASCII

용례

SELECT ASCII('A')

SELECT ASCII('A') FROM DUAL

결과

65

65

è  MSSQL이든 ORacle이든 ‘’ 안에 여러 개의 문자가 있어도 가장 좌측 값만 반환합니다.

, SELECT ASCII(‘A’)  SELECT ASCII(‘ABCDEFG’) 나 결과는 같습니다.

 

 

2.     문자 합치기


구분

MSSQL

Oracle

함수

+

CONCAT 또는 ||

용례

SELECT '동해물과' + '백두산이'

1. SELECT '동해물과 ' || '백두산이' FROM DUAL

2. SELECT CONCAT('동해물과 ','백두산이') FROM DUAL

결과

동해물과 백두산이

동해물과 백두산이

 

 

3.     ASCII 코드를 문자로 변환하기


구분

MSSQL

Oracle

함수

CHAR

CHR

용례

SELECT CHAR(67)

SELECT CHR(67) FROM DUAL

결과

C

C

è  참고로 9번은 TAB, 10 LF(Line Feed), 13번은 CR(Carriage Return) 입니다.

 

 

4.     좌측에서 몇 번째에 해당 문자가 있는지 알려주기


구분

MSSQL

Oracle

함수

CHARINDEX

INSTR

용례

SELECT CHARINDEX('마이', '고마해라. 마이 무우따아이가?')

SELECT INSTR('고마해라. 마이 무우따 아이가?','마이' ) FROM DUAL

결과

7

7

è  MSSQL Oracle의 함수사용 순서가 다릅니다.

è  MSSQL에는 패턴찾기에 PATINDEX를 많이 사용합니다. 위와 같은 결과를 얻으려면

SELECT PATINDEX('%마이%', '고마해라. 마이 무우따 아이가?')

처럼 사용하면 됩니다.(와일드 카드 사용 가능)

 

 

5.     대문자 변환, 소문자 변환


구분

MSSQL

Oracle

함수

UPPER / LOWER

UPPER / LOWER

용례

SELECT UPPER('aBcDeF'),LOWER('aBcDeF')

SELECT UPPER('aBcDeF'), LOWER('aBcDeF') FROM DUAL

결과

ABCDEF abcdef

ABCDEF abcdef

  

 

6.     좌측공간을 특정 문자로 채워주기


구분

MSSQL

Oracle

함수

지원하지 않음(없음)

LPAD

용례

-

SELECT LPAD('13579',10, '0') FROM DUAL

결과

-

0000013579

è  MSSQL에선 없는 함수이기 때문에 아래와 같이 사용자함수를 만들어서 사용하기도 합니다.


-- 1. FUNCTION 만들기

CREATE FUNCTION dbo.UFN_LPAD

(

       @INPUT VARCHAR(8000),

       @COUNT AS INT,

       @FILLCHAR AS CHAR(1)=' '

)

RETURNS varchar(200)

AS

BEGIN

RETURN

       CASE

             WHEN LEN(@INPUT) >= @COUNT THEN LEFT(@INPUT, @COUNT)

       ELSE

             LEFT(REPLICATE(@FILLCHAR, @COUNT), @COUNT-LEN(@INPUT)) + @INPUT

       END

END

 

 

-- 2. SAMPLE

SELECT dbo.UFN_LPAD('12',10,'0') AS PR_KEY

 --> 결과

 0000000012

 

 

 

7.     우측공간을 특정 문자로 채워주기


구분

MSSQL

Oracle

함수

지원하지않음(없음)

RPAD

용례

-

SELECT RPAD('13579',10, '0') FROM DUAL

결과

-

1357900000

è  MSSQL에선 없는 함수이기 때문에 UFN_LPAD처럼 함수를 만들어서 씁니다.

다만, REPLICATE라는 함수가 있는데, 이것은 특정문자를 연속적으로 채워 줄 뿐, RPAD와는 조금 다릅니다.


-- 사용례

SELECT REPLICATE('0',10)

 --> 결과

 0000000000

   또한, SPACE라는 함수는 공백만 채워줍니다.


-- 사용례

SELECT '나의' + SPACE(10) + ''

 --> 결과

 나의         

 

 

8.     /우 공백 없애주기


구분

MSSQL

Oracle

함수

LTRIM / RTRIM

LTRIM / RTRIM

용례

SELECT LTRIM('  아버지'), RTRIM('어머니 ')

SELECT LTRIM('  아버지'), RTRIM('어머니  ') FROM DUAL

결과

아버지   어머니  à (공백제거됨)

아버지   어머니  à (공백제거됨)

 

 

9.     문자의 음성표현을 가지는 문자열을 반환. 국내에서는 흔히 사용하지 않음(한글 동작 안함)

b, f, p, v = 1

c, g, j, k, q, s, x, z = 2

l = 4

m, n = 5

r = 6


구분

MSSQL

Oracle

함수

SOUNDEX

SOUNDEX

용례

SELECT SOUNDEX ('Smith'), SOUNDEX('Smythe');

SELECT SOUNDEX ('Smith'), SOUNDEX ('Smythe') FROM DUAL

결과

S252     S200

S530     S530

è  어라? 예제에는 같은 것으로 되어 있는데, 실제 결과는 다르네요. -_- 이것 참

 

 

10.   전체 문자열에서 지정한 길이만큼의 문자열 반환


구분

MSSQL

Oracle

함수

SUBSTRING

SUBSTR

용례

SELECT SUBSTRING('1234567890',4,5)

SELECT SUBSTR('1234567890',4,5) FROM DUAL

결과

45678

45678

è  4번째 자리에서 시작해서 다섯 글자를 가져옵니다.


11.   문자열 변환


구분

MSSQL

Oracle

함수

REPLACE

REPLACE

용례

SELECT REPLACE('1234567','123','321')

SELECT REPLACE('1234567','123','321') FROM DUAL

결과

3214567

3214567

è  MSSQL STUFF라는 함수가 있는데요. 이것은 엑셀의 REPLACE와 같습니다.


SELECT STUFF('13579',2,3,'222')

--> 결과

12229

 

 

12.   음절의 첫 글자만 대문자로 변환(Pascal Case)


구분

MSSQL

Oracle

함수

지원하지 않음

INITCAP

용례

-

SELECT INITCAP('we are the world') FROM DUAL;

결과

-

We Are The World

 

 

 

14.   나열한 인수 중 가장 큰 값 / 작은 값을 반환


구분

MSSQL

Oracle

함수

지원하지 않음

GREATEST / LEAST

용례

-

SELECT GREATEST('Z9', '나의','','A341', '999','123')  FROM DUAL;

SELECT LEAST('Z9', '나의','','A341', '999','123')  FROM DUAL;

결과

-

 / 123

è  비교하는 것은, 문자순위(A보다는 Z가 크다. 한글은 자모순서에 의함), 숫자순위(0보다는 9가 크가), 글자수단위(같은 문자로 시작하더라도 결국 글자수가 많은 것이 크다.)

 

 

15.   길이 가져오기, 또는 BYTE 단위 길이 가져오기


구분

MSSQL

Oracle

함수

LEN, DATALENGTH

LENGTH

용례

SELECT LEN('NothingToUse')

SELECT DATALENGTH('NothingToUse')

SELECT LEN('지원하지 않음')

SELECT DATALENGTH('지원하지 않음')

SELECT LENGTH('NothingToUse') FROM DUAL;

SELECT LENGTH('지원하지 않음') FROM DUAL;

결과

12 / 12 / 7 / 13

12 / 7

è  위에서 보시면 알겠지만, BYTE 단위로 길이를 확인하시려면 LEN 이 아닌 DATALENGTH 를 사용하셔야 합니다.

 

 

16.   NULL 일 경우 대체값 표시.


구분

MSSQL

Oracle

함수

ISNULL

NVL

용례

SELECT ISNULL(QTY1,100) FROM A_TEMP

SELECT NVL(QTY1,100) FROM A_TEMP;

결과

100 (값이 NULL일 경우)

100 (값이 NULL 일 경우)

 

 

17.   숫자형을 문자형으로 변환


구분

MSSQL

Oracle

함수

STR, CONVERT, CAST

TO_CHAR

용례

SELECT 123 + 456

SELECT STR(123) + STR(456)

SELECT STR(123,3,0) + STR(456,3,0)

SELECT TO_CHAR(123) || TO_CHAR(456) FROM DUAL;

SELECT 123 || 456 FROM DUAL;

결과

579

123       456

123456

123456

123456

è  MSSQL STR는 기본 자릿수가 10자리입니다.

è  Oracle에서는 위에서 보시다시피 숫자형태를 Concat하더라도 자동적으로 문자로 나옵니다.

è  물론 MSSQL에서는 CONVERT CAST를 훨씬 더 많이 사용합니다.


SELECT CONVERT(VARCHAR(3),123) + CONVERT(VARCHAR(3),456)

--> 결과

123456

 

 

18.   문자형을 숫자형으로 변환


구분

MSSQL

Oracle

함수

CONVERT, CAST

TO_NUMBER

용례

SELECT '123' + '456'

SELECT CONVERT(INT,'123') + CONVERT(INT,'456')

SELECT CAST('123' AS INT) + CAST('456' AS INT)

SELECT TO_NUMBER('123') + TO_NUMBER('456') FROM DUAL;

결과

123456 / 579 / 579

579

 

 

19.   조건처리 구문


구분

MSSQL

Oracle

함수

CASE

CASE (DECODE)

è  MSSQL CASE문은 여러 개의 조건 중 맞는 결과를 표시하는 것이고, Oracle DECODE는 참/거짓에 따라 결과를 표시합니다.

1)     MSSQL CASE SAMPLE


-- 1. 테이블생 

CREATE TABLE CASE_STUDY

(PKEY INT PRIMARY KEY,

DATA1 VARCHAR(20),

DATA2 VARCHAR(30)

);

 

-- 2. 자료 입력

INSERT INTO CASE_STUDY (PKEY, DATA1, DATA2) VALUES (1, 'A', '');

INSERT INTO CASE_STUDY (PKEY, DATA1, DATA2) VALUES (2, 'B', '');

INSERT INTO CASE_STUDY (PKEY, DATA1, DATA2) VALUES (3, 'C', '');

INSERT INTO CASE_STUDY (PKEY, DATA1, DATA2) VALUES (4, 'D', '');

INSERT INTO CASE_STUDY (PKEY, DATA1, DATA2) VALUES (5, 'E', '');

 

-- 3. 데이터 출력

SELECT

       PKEY,

       CASE

             WHEN PKEY = 1 THEN DATA1

             WHEN PKEY = 2 THEN DATA2

             WHEN PKEY = 3 THEN DATA1

             ELSE DATA2

       END AS DATA

FROM

       CASE_STUDY

;

 

-- 4. 결과

1      A      -- 1  DATA1

2           -- 2  DATA2

3      C      -- 3  DATA1

4           -- 아니면 DATA2

5           -- 아니면 DATA2

 

2)     같은 자료를 Oracle DECODE를 사용할 경우


 

-- 1. 테이블생 

CREATE TABLE CASE_STUDY

(

  PKEY NUMBER(9),

  DATA1 VARCHAR2(20),

  DATA2 VARCHAR2(30)

);

 

-- 2. 자료 입력

INSERT INTO CASE_STUDY (PKEY, DATA1, DATA2) VALUES (1, 'A', '');

INSERT INTO CASE_STUDY (PKEY, DATA1, DATA2) VALUES (2, 'B', '');

INSERT INTO CASE_STUDY (PKEY, DATA1, DATA2) VALUES (3, 'C', '');

INSERT INTO CASE_STUDY (PKEY, DATA1, DATA2) VALUES (4, 'D', '');

INSERT INTO CASE_STUDY (PKEY, DATA1, DATA2) VALUES (5, 'E', '');

 

-- 3. 데이터 출력

SELECT

       PKEY,

    DECODE(PKEY, 1, DATA1,

        DECODE(PKEY, 2, DATA2,

          DECODE(PKEY, 3, DATA1,

          DATA2)

         )

       ) AS DATA

FROM

       CASE_STUDY

   

 -- 또는

 SELECT

       PKEY,

    DECODE(PKEY, 1, DATA1,

          2, DATA2,

          3, DATA1,

          DATA2) AS DATA

FROM

       CASE_STUDY

   

 

-- 4. 결과

1      A      -- 1  DATA1

2           -- 2  DATA2

3      C      -- 3  DATA1

4           -- 아니면 DATA2

5           -- 아니면 DATA2

 

è  Oracle 8.1.7부터는 MSSQL과 거의 동일한 CASE문을 제공합니다.

위 구문을 MSSQL 구문과 동일하게 하셔도 결과는 같습니다.


20.   지금(Right Now) 가져오기


구분

MSSQL

Oracle

함수

GETDATE()

SYSDATE

용례

SELECT GETDATE()

SELECT SYSDATE FROM DUAL;

결과

2010-11-07 11:50:08.700

2010/11/07 11:50:09

 

è  MSSQL 2008에서는 SYSDATETIME() 을 통해서 더 상세하게 사용이 가능합니다.(DATETIME2)


SELECT SYSDATETIME()

-- 결과

2010-11-07 11:52:25.9900000

 

 

21.   일자 더하기 / 빼기


구분

MSSQL

Oracle

함수

DATEADD

+ / -

용례

SELECT GETDATE();

SELECT DATEADD(d,1,GETDATE());

SELECT DATEADD(hh,5,DATEADD(d,1,GETDATE()));

SELECT DATEADD(d,-1,GETDATE());

SELECT SYSDATE FROM DUAL;

SELECT SYSDATE + 1 FROM DUAL;

SELECT SYSDATE + 1.5 FROM DUAL;

결과

2010-11-07 11:57:38.140

2010-11-08 11:57:38.140

2010-11-08 16:57:38.140

2010-11-06 11:57:38.140

2010/11/07 11:58:09

2010/11/08 11:58:09

2010/11/08 23:58:09
2010/11/06 11:58:09

è  위 결과를 보시면 아시겠지만, Oracle에서는 소수점 단위로 일자계산이 가능합니다. MSSQL에서는 일자에 소수점을 사용해도 인식이 불가능합니다.

 

 

22.   일자 차이 계산


구분

MSSQL

Oracle

함수

DATEDIFF

+ / -

용례

SELECTDATEDIFF(dd,'2010/10/07',GETDATE())

SELECT SYSDATE - TO_DATE('2010/10/07') FROM DUAL;

결과

31

31.39103009259259259259259259259259259259

è  위 결과에도 나타나듯이, MSSQL에서는 일자로 지정하면 딱 떨어지지만, Oracle에서는 특별히 지정하지 않는 한 소수점까지 나타냅니다.

 

 

23.   해당 월의 마지막 날 가져오기


구분

MSSQL

Oracle

함수

지원하지 않음

LAST_DAY

용례

-

SELECT LAST_DAY(to_date('2010/11/15', 'yyyy/mm/dd')) FROM DUAL;

결과

-

2010/11/30 00:00:00

è  MSSQL에서는 아래와 같이 처리할 수 있습니다.


SELECT DATEADD(d,-1,CONVERT(DATETIME,CONVERT(CHAR(6),DATEADD(m,1,'2010-11-15'),112) + '01'))

-- 설명 : 해당일에 1개월을 더한 ,  달의 1일에서 하루를  날을 가져옵니다.

-- 결과

2010-11-30 00:00:00.000

 

 

24.   Time Zone에 의한 시간 변환


구분

MSSQL

Oracle

함수

지원하지 않음

NEW_TIME

용례

-

SELECT NEW_TIME (TO_DATE ('2010/11/07 13:45', 'yyyy/mm/dd HH24:MI'), 'AST', 'MST') FROM DUAL;

결과

-

2010/11/07 10:45:00

è  AST : 대서양 표준시(캐나다 동부, 푸에르토리고, 버진아일랜드 등, 그리니치 표준시보다 4시간 늦음)
MST :
 산악 표준시(로키 산맥에 가까운 미국과 캐나다 일부 지역의 동계 표준시, 그리니치 표준시보다 7시간 늦음)

è  Oracle Zone 


Value

Description

AST

Atlantic Standard Time

ADT

Atlantic Daylight Time

BST

Bering Standard Time

BDT

Bering Daylight Time

CST

Central Standard Time

CDT

Central Daylight Time

EST

Eastern Standard Time

EDT

Eastern Daylight Time

GMT

Greenwich Mean Time

HST

Alaska-Hawaii Standard Time

HDT

Alaska-Hawaii Daylight Time

MST

Mountain Standard Time

MDT

Mountain Daylight Time

NST

Newfoundland Standard Time

PST

Pacific Standard Time

PDT

Pacific Daylight Time

YST

Yukon Standard Time

YDT

Yukon Daylight Time


 

è  MSSQL DATETIMEOFFSET이라는 것이 있지만, 이것은 표준시간대 인식일 뿐 구조는 다릅니다.

 

 

25.   해당일자 다음에 오는 해당 요일 반환


구분

MSSQL

Oracle

함수

지원하지 않음

NEXT_DAY

용례

-

SELECT NEXT_DAY('2010/11/07', '월요일') FROM DUAL;

결과

-

2010/11/08 00:00:00

è  보시다시피 2010년 11 7일 이후에 처음 오는 월요일을 반환합니다.
하지만, 주의할 사항은 국가설정에 따라 일자설정이 다릅니다
.
미국으로 되어 있으면 SELECT NEXT_DAY('10-Nov-07', 'MONDAY') FROM DUAL; 으로 하셔야 합니다.

 

 

26.   지정한 날짜의 특정 부분을 나타내는 문자열을 반환합니다.


구분

MSSQL

Oracle

함수

DATENAME, DATEPART …

TO_CHAR

용례

SELECT DATENAME(day, '2010-11-07')

SELECT DATENAME(month, '2010-11-07')

SELECT DATENAME(year, '2010-11-07')

 

SELECT DATEPART(day,'2010-11-07')

SELECT DAY('2010-11-07')

SELECT TO_CHAR(TO_DATE('2010/11/07'), 'DD') FROM DUAL;

SELECT TO_CHAR(TO_DATE('2010/11/07'), 'MM') FROM DUAL;

SELECT TO_CHAR(TO_DATE('2010/11/07'), 'YYYY') FROM DUAL;

결과

7

11

2010

 

7

7

07

11

2010

è  MSSQL DATENAME의 경우 2005 이전 버전에 맞춰져 있습니다. 그 이상의 버전에서는 용례 아랫부분을 참조하시면 됩니다.
Oracle
의 경우엔 TO_CHAR를 만능으로 써서 할 수 있습니다.

다만 실제로 숫자처럼 쓰시려면 TO_NUMBER를 통해서 숫자형으로 변환해 주셔야 합니다.

 

 

27.   문자형을 날짜형으로 변환


구분

MSSQL

Oracle

함수

CONVERT / CAST

TO_DATE

용례

SELECT CONVERT(DATETIME,'2010-11-07')

SELECT CONVERT(DATETIME,'2010-11-07 12:20:23')

SELECT CONVERT(DATETIME,'20101107')

SELECT CONVERT(DATETIME,'20101107 12:20:23')

 

SELECT CAST('20101107 12:20:23' ASDATETIME)

SELECT TO_DATE('2010-11-07') FROM DUAL;

SELECT TO_DATE('2010/11/07 12:20:23', 'YYYY/MM/DD HH24:MI:SS') FROM DUAL;

SELECT TO_DATE('20101107','YYYYMMDD') FROM DUAL;

SELECT TO_DATE('11/07/2010','MM/DD/YYYY') FROM DUAL;

결과

2010-11-07 00:00:00.000

2010-11-07 12:20:23.000

2010-11-07 00:00:00.000

2010-11-07 12:20:23.000

 

2010-11-07 12:20:23.000

2010/11/07 00:00:00

2010/11/07 12:20:23

2010/11/07 00:00:00

2010/11/07 00:00:00

è  Oracle의 경우엔 Format_Mask를 지정해 주시는 것이 관례입니다.

 

 

28.   날짜형을 문자형으로 변환


구분

MSSQL

Oracle

함수

CONVERT / CAST

TO_CHAR

용례

SELECT CONVERT(CHAR(8),GETDATE(),112)

SELECT CONVERT(CHAR(10),GETDATE(),120)

SELECT CONVERT(CHAR(20),GETDATE(),120)

SELECT CONVERT(CHAR(20),GETDATE())

 

SELECT CAST(GETDATE() AS CHAR(20))

SELECT TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS') FROM DUAL;

SELECT TO_CHAR(SYSDATE, 'YYYYMMDD') FROM DUAL;

SELECT TO_CHAR(SYSDATE,'MM/DD/YYYY') FROM DUAL;

결과

20101107

2010-11-07

2010-11-07 17:41:21

11  7 2010  5:42PM

 

11  7 2010  5:41PM

2010-11-07 17:43:53

20101107

11/07/2010

è  문자형과 날짜형 변환은 위처럼 사용이 가능한데요,

MSSQL에서의 자세한 사항은 강산아님의 아티클

(http://www.sqler.com/?mid=bColumn&page=4&document_srl=265068)

을 참조해 주세요.

 

'01.MS-SQL' 카테고리의 다른 글

[MSSQL]Windows 64Bit And MS-SQL 32Bit  (0) 2012.12.19
[MSSQL]Transaction Kill  (0) 2012.12.19
[MSSQL]데이터 파일 축소  (0) 2012.12.19
[MSSQL]테이블별 용량 확인  (0) 2012.12.19
[MSSQL]자주 사용하는 명령어  (0) 2012.12.19
Posted by redkite
, |

테이블별 사용 용량


SELECT table_name = convert(varchar(30), min(o.name))
 , table_size = ltrim(str(sum(cast(reserved as bigint)) * 8192 / 1024.,15,0) + 'KB')
FROM sysindexes i
  INNER JOIN
  sysobjects o
  ON (o.id = i.id)
WHERE i.indid IN (0, 1, 255)
AND  o.xtype = 'U'
GROUP BY i.id


용량별 소팅


SELECT table_name = convert(varchar(30), min(o.name))
 , table_size = convert(int, ltrim(str(sum(cast(reserved as bigint)) * 8192 / 1024., 15, 0))), UNIT = 'KB'
FROM sysindexes i
  INNER JOIN
  sysobjects o
  ON (o.id = i.id)
WHERE i.indid IN (0, 1, 255)
AND  o.xtype = 'U'
GROUP BY i.id
ORDER BY table_size DESC


테이블별 Row 수


SELECT o.name
 , i.rows
FROM sysindexes i
  INNER JOIN
  sysobjects o
  ON i.id = o.id
WHERE i.indid < 2
AND  o.xtype = 'U'
ORDER BY i.id

 

'01.MS-SQL' 카테고리의 다른 글

[MSSQL]Windows 64Bit And MS-SQL 32Bit  (0) 2012.12.19
[MSSQL]Transaction Kill  (0) 2012.12.19
[MSSQL]데이터 파일 축소  (0) 2012.12.19
[MSSQL]DateTime 변환 함수  (0) 2012.12.19
[MSSQL]자주 사용하는 명령어  (0) 2012.12.19
Posted by redkite
, |

use MonitoringDB

DBCC updateusage ("MonitoringDB")  == space update

EXEC sp_updatestats

EXEC sp_spaceused @updateusage = "TRUE"



쿼리분석기


1. 로그(ldf)를 백업할 DB 선택

use tceng


2. 로그파일의 정보 확인

dbcc loginfo


3. mdf, ldf 정보 확인

exec sp_helpfile


4. 로그 백업(먼저 c:\backup 폴더를 생성한 후에 실행)

backup Log tceng to disk='c:\backup\tceng.bak'

go


5. 로그 축소

backup Log tceng with truncate_only


6. 로그 삭제

backup Log tceng with no_log


7. 로그 파일 재생성(10MB)

dbcc shrinkfile(tceng, 10)


Enterprise Manager


tceng DB의 속성 정보에서 새롭게 생성된 로그 파일 확인

트랜잭션로그 탭에서 최대 사이즈 지정(MB단위)


MDF, LDF 파일을 가지고 DB 복원 하기

복원할 DB : tceng(DB도 같이 생성되므로 미리 생성하지 않는다.)


exec sp_attach_db 'tceng', 'c:\tceng.mdf', 'c:\tceng.ldf'

go 

'01.MS-SQL' 카테고리의 다른 글

[MSSQL]Windows 64Bit And MS-SQL 32Bit  (0) 2012.12.19
[MSSQL]Transaction Kill  (0) 2012.12.19
[MSSQL]데이터 파일 축소  (0) 2012.12.19
[MSSQL]DateTime 변환 함수  (0) 2012.12.19
[MSSQL]테이블별 용량 확인  (0) 2012.12.19
Posted by redkite
, |

최근에 달린 댓글

최근에 받은 트랙백

글 보관함