http://www.artfulsoftware.com/infotree/queries.php
'SQL'에 해당되는 글 14건
- 2015.10.14 mysql 쿼리들
- 2012.09.10 Transaction Isolation Level을 이해하기
- 2011.01.09 MS-SQL 2008 MERGE, OUTPUT
- 2010.05.11 Transaction Log 자르기
- 2010.04.01 특정 테이블을 기준으로 일괄 업데이트(데이터 동기화)
- 2010.03.29 SQL Parent Row 찾기!
- 2010.03.19 MS-SQL DB 백업 스크립트
- 2009.10.29 MS-SQL : stuff, isnull, coalesce 시스템 함수!
- 2009.04.03 시스템 프로시저들.. 도움말 주소
- 2009.03.10 C#과 SQL 모두에서 암호화 하기.!!
Transaction Isolation Level을 이해하기
출처 : http://support.microsoft.com/kb/601430/ko
NF: Transaction Isolation Level을 이해하기
요약
추가 정보
ANSI에서 작성된 SQL-92 표준은 네 종류의 Isolation Level을 정의하고 있으며 SQL Server 7.0은 이 표준을 준수합니다. Isolation Level을 조정하는 경우 동시성이 증가되는데 반해 데이터의 무결성에 문제가 발생할 수 있거나, 데이터의 무결성을 완벽하게 유지하는 데 반하여 동시성이 떨어질 수 있으므로 그 기능을 완벽하게 이해한 후에 사용해야 합니다.
다음은 SQL Server에서 지원하는 네 종류의 Transaction Isolation Level입니다.
- Read Committed
- Repeatable Read
- Serializable
- Read Uncommitted Isolation Level
- SELECT 문장을 수행하는 경우 해당 데이터에 Shared Lock이 걸리지 않는 Level입니다. 따라서, 어떤 사용자가 A라는 데이터를 B라는 데이터로 변경하는 동안 다른 사용자는 B라는 아직 완료되지 않은(Uncommitted 혹은 Dirty) 데이터 B를 읽을 수 있습니다. - Read Committed Isolation Level
- SQL Server가 Default로 사용하는 Isolation Level입니다. 이 Level에선 SELECT 문장이 수행되는 동안 해당 데이터에 Shared Lock이 걸립니다. 그러므로, 어떠한 사용자가 A라는 데이터를 B라는 데이터로 변경하는 동안 다른 사용자는 해당 데이터에 접근할 수 없습니다. - Repeatable Read Isolation Level
- 트랜잭션이 완료될 때까지 SELECT 문장이 사용하는 모든 데이터에 Shared Lock이 걸리므로 다른 사용자는 그 영역에 해당되는 데이터에 대한 수정이 불가능합니다. 가령, Select col1 from A where col1 between 1 and 10을 수행하였고 이 범위에 해당하는 데이터가 2건이 있는 경우(col1=1과 5) 다른 사용자가 col1이 1이나 5인 Row에 대한 UPDATE이 불가능합니다. 하지만, col1이 1과 5를 제외한 나머지 이 범위에 해당하는 Row를 INSERT하는 것이 가능합니다. - Serializable Isolation Level
- 트랜잭션이 완료될 때까지 SELECT 문장이 사용하는 모든 데이터에 Shared Lock이 걸리므로 다른 사용자는 그 영역에 해당되는 데이터에 대한 수정 및 입력이 불가능합니다. 예를 들어, Repeatable Read의 경우 1에서 10 사이에 해당되는 데이터에 대한 UPADTE이 가능하였습니다. 하지만 이 Level에서는 UPDATE 작업도 허용하지 않습니다.
사용 방법:즉, SET 문장을 이용하여 Transaction Isolation Level을 정의하게 되므로 해당 Session에서만 Isolation Level이 적용됩니다.SET TRANSACTION ISOLATION LEVEL { READ COMMITTED | READ UNCOMMITTED | REPEATABLE READ | SERIALIZABLE }
참조
속성
MS-SQL 2008 MERGE, OUTPUT
1. MERGE
(MS-SQL 2008, Oracle 9i 에서 생김)
두 테이블간의 데이터를 합치는 작업이다.
단 하나의 트랜잭션에서 작업이 진행되어야 함.
Source Table과 Target 테이블의 데이터를 비교했을때
겹치는부분(빨간색)은 Update, Source Table 에만 있는 데이터는 INSERT
작업을 진행한다.
create table #SourceTable --MERGE 작업을 진행할 Target |
2. OUTPUT
A 테이블에 DML(update, insert, delete)작업이 일어나고
B 테이블에 같은 조건으로 Insert 를 할 수 있다.
단, 하나의 트랜잭션에서 작업이 진행되어야 한다.
Insert 일때는 inserted Object 가 생성된다.
Delete 일때는 deleted Object 가 생성된다.
Update 일때는 deleted Object와 inserted Object 가 둘다 생성된다.
이를 이용하여 B테이블에도 데이터를 입력할 수 있다.
create table #1st insert into #1st(b) select * update #1st
|
Transaction Log 자르기
Transaction Log 자르기
1. MS-SQL 2005
backup log [dbname] with no_log
dbcc shrinkfile('IGROO_DB_Log',1)
2. MS-SQL 2008
ALTER DATABASE [dbname] SET RECOVERY SIMPLE
GO
DBCC SHRINKFILE(2, 1)
GO
ALTER DATABASE [dbname] SET RECOVERY FULL
특정 테이블을 기준으로 일괄 업데이트(데이터 동기화)
A 테이블과 B 테이블의 데이터를 동기화 시킬 때
A 테이블의 키와
B 테이블의 키가 같다고 가정하고
키를 기준으로 조인을 시키고
조인된 로우들의 데이터를 동기화 시킨다.
-- 테스트 테이블을 만들고
create table test1
(
cn varchar(100)
,data1 varchar(100)
,data2 varchar(100)
,data3 varchar(100)
,data4 varchar(100)
)
-- 테스트 데이터 삽입
insert test1 values('cn1','data1','data11','data111','data1111')
insert test1 values('cn2','data2','data22','data222','data2222')
insert test1 values('cn3','data3','data33','data333','data3333')
insert test1 values('cn4','data4','data44','data444','data4444')
insert test1 values('cn5','data5','data55','data555','data5555')
insert test1 values('cn6','data6','data66','data666','data6666')
insert test1 values('cn7','data7','data77','data777','data7777')
insert test1 values('cn8','data8','data88','data888','data8888')
insert test1 values('cn9','data9','data99','data999','data9999')
-- 같은 구조의 테이블을 복사
select * into test2 from test1
-- 테스트를 위하여 복사된 테이블의 데이터를 일부 변경 한다
update test2 set data1 ='changedata1',
data2 ='changedata2',data3 ='changedata3',data4 ='changedata4'
where cn in ('cn2','cn3','cn4','cn5')
-- select 를 이용하여 데이터가 다른 것을 확인
select * from test1
select * from test2
-- 원본 테이블과 데이터가 약간 변경된 테이블을 조인 후
-- update 절의 set 구문에서 컬럼 매핑 시킨다.
update test2 SET data1 = t1.data1, data2 = t1.data2,
data3 = t1.data3, data4 = t1.data4
from test1 t1 JOIN test2 t2
ON t1.cn = t2.cn
데이터 동기화 끝.
SQL Parent Row 찾기!
간단한 쿼리문..
1시간동안 해맸던.
---------------------------
간단한 테스트 테이블
---------------------------
create table Test
(
child varchar(100),
parent varchar(100),
data varchar(100)
)
------------------------------------
테스트 데이터 : child 컬럼의 데이터는 null(최상위) 이거나 부모를 가지고 있다
------------------------------------
insert into Test values('1', null,'data1')
insert into Test values('2', '1','data2')
insert into Test values('3', '1','data3')
insert into Test values('4', '2','data4')
insert into Test values('5', '1','data5')
insert into Test values('6', '1','data6')
insert into Test values('7', '3','data7')
insert into Test values('8', '3','data8')
insert into Test values('9', '1','data9')
------------------------------------
셀프 조인을 통해(left join) 부모데이터와
자식 데이터를 나란히 위치 시킨다
------------------------------------
select t1.child , t1.parent, t1.data childData, t2.data parentData
from Test t1 left outer join
Test t2 on t1.parent = t2.child
------------------------------------
원래 결과
child parent data
1 NULL data1
2 1 data2
3 1 data3
4 2 data4
5 1 data5
6 1 data6
7 3 data7
8 3 data8
9 1 data9
쿼리후 나온 결과
child parent childData parentData
1 NULL data1 NULL
2 1 data2 data1
3 1 data3 data1
4 2 data4 data2
5 1 data5 data1
6 1 data6 data1
7 3 data7 data3
8 3 data8 data3
9 1 data9 data1
끝
MS-SQL DB 백업 스크립트
귀찮은 디비 백업 스크립트로 간단히 백업
--SQL 에서 폴더 생성 가능하게 셋팅
--SP_CONFIGURE XP_CMDSHELL ,1
--RECONFIGURE
--날짜에 맞게 폴더 생성
DECLARE @COMMAND NVARCHAR(100)
declare @folderName NVARCHAR(100)
set @folderName = N'D:\백업\DB백업\' + CONVERT(VARCHAR(10),GETDATE(), 121)
SET @COMMAND=N'MD ' + @folderName
EXEC MASTER..XP_CMDSHELL @COMMAND
GO
--적당히 쓸 변수들
DECLARE @QUERY NVARCHAR(MAX)
DECLARE @PARAMS NVARCHAR(100)
DECLARE @DBNAME2 NVARCHAR(100)
DECLARE @PATH2 NVARCHAR(200)
DECLARE @ROWCOUNT INT;
DECLARE @COUNT INT;
--백업할 디비명들 저장
DECLARE @TABLE TABLE(TABLENAME NVARCHAR(100))
INSERT INTO @TABLE VALUES ('디비명');
....
..
.
SET @COUNT =1
SELECT @ROWCOUNT = COUNT( TABLENAME) FROM @TABLE
-- 테이블변수에서 디비명 읽어와서 백업
WHILE @COUNT<@ROWCOUNT +1
BEGIN
SELECT TOP 1 @DBNAME2 = TABLENAME FROM @TABLE
WHERE TABLENAME IN (
SELECT TABLENAME
FROM(
SELECT TABLENAME, ROW_NUMBER() OVER (ORDER BY TABLENAME) NUM FROM @TABLE
) t1 WHERE NUM = @COUNT
)
--D:\백업\DB백업\2010-03-19\ACDDYN_2010-03-19.BAK
SELECT @PATH2 = N'D:\백업\DB백업\' + CONVERT(VARCHAR(10),GETDATE(), 121) +'\'+ @DBNAME2 +N'_' +CONVERT(VARCHAR(10),GETDATE(), 121)+ N'.BAK'
SET @QUERY = N'BACKUP DATABASE @DBNAME TO DISK=@PATH'
SET @PARAMS = N' @DBNAME NVARCHAR(100),@PATH NVARCHAR(200)'
EXEC sp_executesql @QUERY,@PARAMS, @DBNAME =@DBNAME2, @PATH = @PATH2
SET @COUNT = @COUNT +1;
END
끝.
MS-SQL : stuff, isnull, coalesce 시스템 함수!
구문
STUFF ( character_expression , start , length ,character_expression )
character_expression : Base 문자데이터 식
start : 시작 위치(1부터 시작)
length : 삭제할 길이 (character_expression 에서 삭제함)
character_expression : 삽입할 문자 데이터식
SELECT STUFF('abcdef', 2, 3, '123456');
abcdef 문자에서 2번째 부터 시작하여 3 길이만큼 글자를 삭제
-> bcd 삭제 후 aef 글자에 123456 삽입 함 위치는 start(2) 위치
결과값 : a123456ef
2. ISNULL
구문
ISNULL ( check_expression , replacement_value )check_expression : Null 인지 Check 할 모든 식replacement_value : Null 일 경우 대입할 값
SELECT ISNULL('B', 'A')
결과값 : B
SELECT ISNULL(NULL, 'A')
결과값 :A
3. coalesce
구문
COALESCE ( expression [ ,...n ] )여러개의 식 중 Null 이 아닌 값을 출력(리턴)SELECT COALESCE ( NULL,NULL,NULL,'A')결과값 :A
--> ISNULL 과의 차이는 ISNULL 은 식이 2개로 고정이지만,COALESCE 은 2개 이상의 식에 대해서 NULL 체크 가능
시스템 프로시저들.. 도움말 주소
ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.ko/tsqlref9/html/2ce018e9-1a3b-4530-a87d-842456a555ad.htm
C#과 SQL 모두에서 암호화 하기.!!
C#에서의 암호화
System.Web.Security 네임 스페이스 에서
//"aaa" 글자를 "sha1" 알고리즘을 이용하여 암호화 한다.("md5" 알고리즘을 사용해도 됨.)
string pass1 = FormsAuthentication.HashPasswordForStoringInConfigFile("aaa", "sha1");
Console.WriteLine(pass.Equals(pass1)); // True
MS - SQL 에서의 암호화
1. 간단한 테이블을 만든다. (binary 타입의..)
create table a
(
id varchar(100),
pass varbinary(100)
)
2. PwdEncrypt() 를 이용하여 값을 입력한다.
insert into a values('id1', PwdEncrypt('aaa'))
그러면 입력된 값은
0x01009DA90A8CBBB84FECFF392EDCD8F358A9EB2F0B818D7A9C27
이러한 복잡한 값이 된다.
3. PwdCompare() 를 이용하여 값을 비교한다.
select PwdCompare('aaa',pass) from a where id='id1'
리턴 값은 0 혹은 1
끝.