관리자
글쓰기

외래키를 설정하는 이유는 무결성을 채우기 위함입니다.
관계성 있는 테이블들끼리 외래키를 설정을 하면
쓰레기 데이터들이 쌓이지 않겠죠.

* 실습하기 *

create table 시험
(시험번호 int constraint PK_시험_시험번호 primary key, 시험명 char(20))

insert into 시험 values(10, '국어')
insert into 시험 values(20, '영어')
insert into 시험 values(30, '수학')

create table 응시자
(
 번호 int IDENTITY (1,1)
, 이름 char(10)
, 시험번호 int
)

insert into 응시자 values('오버탑', 10)
insert into 응시자 values('오버탑', 20)
insert into 응시자 values('오버탑', 30)
insert into 응시자 values('오버탑', 40)

여기까지 데이터들이 생성되었다가 가정하자

그럼 외래키를 설정해보자

1.T-SQL 에서 생성하기

alter table 응시자
add constraint FK_응시자_시험번호
 foreign key(시험번호) references 시험(시험번호)
-- on update cascade
-- on delete cascade

여기서잠깐??
on update cascade -- 옵션 1
on delete cascade --옵션 2

 cascade : 설정 체크
 no action : 설정 체크해제

 - 에러메세지 -
서버: 메시지 547, 수준 16, 상태 1, 줄 1
ALTER TABLE 문이 COLUMN FOREIGN KEY 제약 조건
'FK_응시자_시험번호'과(와) 충돌되었습니다.
충돌은 'PushUser' 데이터베이스, '시험', column '시험번호'
테이블에서 발생했습니다.

왜 생겼을까여 ??
답 : 참조하는 응시자 테이블의 시험번호중에 참조당하는 시험 테이블에 없어서 생긴다. (시험번호 40)

delete from 응시자 where 시험번호 = 40

삭제 후에 alert 문을 실행하면 외래키가 생성이 된다.

TIP. 제약조건 삭제는

 alter table 응시자
 drop FK_응시자_시험번호


2. EM 에서 생성하기

사용자 삽입 이미지

사용자 삽입 이미지


TIP. 옵션설정.
  파란색 박스 1 : on update cascade -- 옵션 1
  파란색 박스 2 : on delete no action --옵션 2

각 옵션에 따라 테스트 해볼까여??
참조자(응시자자)는 모든 액션이 실행되지만 참조당하는자(시험)은
외래키 제약조건에 오류가 발생합니다.

select * from 시험
select * from 응시자

// 참조자에 해당하는 값이 있을 경우에 수정/삭제하기
-- update 시험 set 시험번호 = 50 where 시험번호 = 10
-- delete from 시험 where 시험번호 = 10
- 에러메세지 -
서버: 메시지 547, 수준 16, 상태 1, 줄 1
UPDATE 문이 COLUMN REFERENCE 제약 조건 'FK_응시자_시험'과(와)
충돌되었습니다. 충돌은 'PushUser' 데이터베이스, '응시자', column
'시험번호' 테이블에서 발생했습니다. 문이 종료되었습니다.

// 참조자에 해당하는 값이 없을 경우에 수정/삭제하기

delete from 응시자 where 시험번호 = 30

update 시험 set 시험번호 = 300 where 시험번호 = 30
 - 정상업데이트
select * from 시험

delete from 시험 where 시험번호 = 300
 - 정상삭제

참조자는 언제든지 수정/업데이트가 가능하다.
update 응시자 set 시험번호 = 10 where 시험번호 = 20

// 참조당하는자(시험)를 수정, 삭제가 가능하게 하려면 옵션을 추가하면 된다.

제약조건을 삭제하고 재 설정을 한다.

 alter table 응시자
 drop FK_응시자_시험

 alter table 응시자
 add constraint FK_응시자_시험번호
  foreign key(시험번호) references 시험(시험번호)
  on update cascade
  on delete cascade

select * from 시험
select * from 응시자

update 시험 set 시험번호 = 100  where 시험번호 = 10

select * from 시험
select * from 응시자

시험테이블과 응시자테이블의 시험번호가 동시에 바뀐다. 확인하셨나여 ?

delete 시험 where 시험번호 = 100
select * from 시험
select * from 응시자

이상 옵션에 따라 참조가의 데이터값들의 변화를 알아봤습니다.

결론. 외래키는 데이터 무결성을 위함입니다. DB모델링시 필요한
부분들은 미리 설정을 하셔서 최적화된 데이터를 이용하시면 좋을 것같으네여.


2011/04/08 17:10 2011/04/08 17:10

트랙백 주소 :: http://www.overtop.co.kr/tt2/trackback/365

댓글을 달아 주세요

MSSQL2008 Management Studio를 사용하는 개발자들에게 팁을 하나 주려고 포스팅합니다.
테이블을 생성하고 수정시 이런 경고메세지로 인해서 수정을 못하는 분들이 있을겁니다.

변경 내용을 저장 할수 없습니다. 변경 내뇽을 적용하려면 다음 테이블을
삭제 하고 다시 만들어야 합니다. 다시 만들 수 없는 테이블을 변경
했거나 [테이블을 다시 만들어야 하는 변경 내용 저장 사용 안함 ] 옵션을
설정 했습니다.

MSSQL2008 Management Studio 제약을 걸어놓았더군요. ms에서 왜 그런지는
잘 모르겠구요. 해결 방법은 아래와 같이 해주시면 됩니다.
Management Studio > 도구 > 옵션 > <테이블을 다시 만들어야 하는 변경 내용 저장 사용 안함>
항목을 체크해제 해주시면 됩니다. 아주 간단하죠.

사용자 삽입 이미지

옵션 : 테이블을 다시 만들어야 하는 변경 내용 저장 사용 안 함
테이블을 다시 만들어야 하는 변경 내용을 사용자가 저장할 수 없게 만듭니다.
다음 동작을 수행하려면 테이블을 다시 만들어야 할 수 있습니다.
1. 테이블의 중간에 새 열 추가
2. 열 삭제
3. 열의 Null 허용 여부 변경
4. 열의 순서 변경
5. 열의 데이터 형식 변경
위 경우에 옵션을 제한하네요..

기타 옵션은 아래 링크에서 확인하세요.
http://msdn.microsoft.com/ko-kr/library/ms188490.aspx

Comment). 구글링에서도 검색이 많았나봅니다. 개발자로써 아주 불편한 사항이거든요.
자동검색어에 추가가 되었더군요. 얼마나 검색을 했으면
MS에서도 다음 개발시 참고해서 불편함이 없었으면 좋겠네여.
사용자 삽입 이미지


2010/04/26 12:00 2010/04/26 12:00

트랙백 주소 :: http://www.overtop.co.kr/tt2/trackback/335

댓글을 달아 주세요

  1. 검색맨 2010/12/21 12:11  댓글주소  수정/삭제  댓글쓰기

    검색하길잘했어요.. ㅠ
    다 불편해하는군요

  2. 감사맨 2011/03/04 09:53  댓글주소  수정/삭제  댓글쓰기

    이런 옵션이 있었군요~

    감사합니다~

저장프로시저를 생성하는 중에 연결된서버와의 통신이 빈번히 일어날겁니다.

Select, Insert, Update 처럼 쿼리를 실행할경우에는
SELECT * FROM [연결서버이름].[연결db].[권한계정].테이블
ex) SELECT * FROM AddName.DBName.dbo.테이블
하면 쉽게 결과를 얻을 수 있습니다.

하지만 저장프로시저를 실행할 경우에는
아래와 같은 에러메세지를 볼 수 있습니다.

서버 'AddName'이(가) RPC에 대해 구성되지 않았습니다.

여기서 RPC를 이해하시면 됩니다.
RPC = Remote Procedure Call
이것을 해결하는 방법은 아래와 같습니다. RPC옵션을 TRUE 로 처리하면 끝납니다.

EXEC sp_serveroption '연결서버이름', 'rpc', TRUE
  -- 연결된서버로부터 로컬서버로의 RPC 호출을 활성화
EXEC sp_serveroption '연결서버이름', 'rpc out', TRUE
  -- 로컬서버로부터 연결된서버로의 RPC 호출을 활성화

또는 EM or Management Studio 의 툴에서 직접 설정을 해주시면됩니다.

사용자 삽입 이미지


설정 후에 저장프로시저를 실행하면 결과를 얻을 수 있습니다.

Exec 연결된서버이름.DB이름.권한계정.StoredProcedure문

도움이 되시길..

2010/04/21 15:56 2010/04/21 15:56

트랙백 주소 :: http://www.overtop.co.kr/tt2/trackback/334

댓글을 달아 주세요

  1. 조성구 2010/06/29 17:18  댓글주소  수정/삭제  댓글쓰기

    감사합니다~

    mssql 초보인데 잘보고 가요~

까먹을까봐 올렸습니다.

select convert(varchar, cast('612212375' as money), 1)
select Replace(convert(varchar, cast('612212375' as money), 1), '.00', '')

쿼리를 날릴때 세자리로 끊어서 불러오고 싶을때 쓰면 될듯하다.
왜 저렇게 나오는지는 잘 모르겠다.
쩝.~
2010/04/11 00:26 2010/04/11 00:26
TAG ,

트랙백 주소 :: http://www.overtop.co.kr/tt2/trackback/326

댓글을 달아 주세요

[MSSQL]SQL Server 버전,서비스팩,에디션 알아보는 방법 쿼리

SQL서버를 운영관리를 하다보면
설치버전, 서비스팩 설치유무, 하드웨어사양 등등을 서버문서에 업데이트를
안하면 참으로 난감할때가 있습니다.

저도 가끔 까먹기에 정리를 해봤습니다.


* T-SQL *

1. 실행
SELECT
 @@version as 풀버전
,  SERVERPROPERTY('productversion') as 버전번호
, SERVERPROPERTY ('productlevel') as 서비스팩이름
, SERVERPROPERTY ('edition') as 설치버전


2. 결과(버전별)

사용자 삽입 이미지

사용자 삽입 이미지


3. 풀버전 내용

- 64Bit -
Microsoft SQL Server 2005 - 9.00.1399.06 (X64)  
Oct 14 2005 00:35:21  
Copyright (c) 1988-2005 Microsoft Corporation 
Standard Edition (64-bit)
on Windows NT 5.2 (Build 3790: Service Pack 2)


- 32Bit -
Microsoft SQL Server 2005 - 9.00.4053.00 (Intel X86)  
May 26 2009 14:24:20  
Copyright (c) 1988-2005 Microsoft Corporation 
Standard Edition
on Windows NT 5.2 (Build 3790: Service Pack 2)

위 처럼 운영하는 서버들의 버전을 알아볼 수 있습니다.


Comment.기술적인 내용을 포스팅을 안했었는데
기억력의 감퇴가 느껴지므로 슬슬 포스팅을 해볼까 한다.
그래도 자주 많이는 못할듯.



 -  당신의 지금은 이미 과거일뿐이다. -
2010 Catch Phrase By 오버탑

2010/03/03 11:26 2010/03/03 11:26

트랙백 주소 :: http://www.overtop.co.kr/tt2/trackback/317

댓글을 달아 주세요