database.sarang.net
UserID
Passwd
Database
DBMS
MySQL
PostgreSQL
Firebird
Oracle
Informix
Sybase
ㆍMS-SQL
DB2
Cache
CUBRID
LDAP
ALTIBASE
Tibero
DB 문서들
스터디
Community
공지사항
자유게시판
구인|구직
DSN 갤러리
도움주신분들
Admin
운영게시판
최근게시물
MS-SQL Q&A 2011 게시물 읽기
No. 2011
데이터 베이스 문제 입니다. 한번 풀어보세요
작성자
석이
작성일
2005-06-08 03:51ⓒ
2005-06-08 03:55ⓜ
조회수
7,699

정말 심심해서 한번 풀어 보았습니다.

여러분도 한번 풀어 보세요 나중에 답안을 여러개 모아 보도록 하겠습니다.

잔 가지 나무치기 서비스 문제 입니다.

 

TWIGS TREE TRIMMING SERVICE 문제


SQL Server를 이용하여 다음과 같은 3개의 테이블을 생성하라.


OWNER ( OwnerName , Phone, Street, City, State, Zip)

SERVICE ( DateOfService , OwnerName , Description, AmountBilled, AmountPaid, DateOfPayment)

CHIP_DELIVERY ( CustomerName , DeliveryDate , LoadSize, AmountBilled, AmountPaid, DateOfPayment)


다음의 참조 무결성을 규정하는 관계를 생성하라.


SERVICE.OWNERNAME은 OWNER.OwnerName으로 존재한다.

CHIP_DELIVERY.CustomerName은 OWNER.OwnerName으로 존재한다.


연쇄 갱신과 삭제를 허용한다.


A. 테이블에 샘플 데이터를 넣고 출력하라.


B. 서비스 일정 계획을 관리하는 저장 프로시저를 작성하라. 프로시저는 모든 소유자 데이터와 DateOfService와 Description 데이터를 받는다. 만일 소유자가 이미 데이터베이스에 존재한다면, 기존의 소유자 데이터를 사용한다. 그렇지 않으면 OWNER 테이블의 한 행을 생성하라. 새로운 SERVICE 행을 생성하라. 프로시저를 작성하고 테스트하라.


C. 칩 배달을 위한 일정 계획을 관리하는 저장 프로시저를 작성하라. 프로시저는 모든 소유자 데이터와 DeliveryDate, LoadSize, Amount Billed를 받는다. 만일 이미 소유자가 데이터베이스에 있다면 소유자 데이터를 사용한다. 만일 소유자가 어떠한 체납 SERVICE 또는 CHIP_DELIVERY 레코드를 가지고 있다면 배달 계획을 잡지 마라. 대신 오류 메시지를 출력하라. 체납은 AmountBilled가 널값이 아닌 것을 의미하나 AmountPaid는 널값임을 의미한다.


D. 모든 OWNER와 SERVICE 데이터를 갖는 CustomerService라는 이름의 뷰를 생성하라. CustomerService의 삽입을 위한 INSTEAD OF 트리거를 작성하라. 사용자는 모든 소유자 데이터와 DateOfService와 Description 데이터를 제공한다. 만일 소유자가 데이터베이스에 없다면, OWNER에 새로운 행을 삽입히라. 이 서비스와 관련하여 SERVICE 테이블에 행을 삽입하라. 트리거가 동작함을 입증하라.


D번 문제는 좀 이상한거 같습니다.

뷰에 트리거를 걸어?

무슨 소린지 잘 모르겠지만 테이블 이라 생각하고 한번 만들어 보세요

그럼 데이터 베이스 사랑넷 여러분 화이팅 입니다.

나름대로의 답안은 1주 후 공개 하겠습니다. ^-^ 그때 틀린것도 좀 잡아 주세요

요즘 학생들은 2주 배우고 이런거 푼다네요 ^-^ 놀랠 따름 입니다.

악플 금지 입니다. ^-^


대기업 가서 디비 한번 건드려 보고 싶은 석이가 ㅠ.ㅠ 대용량 미션 크리티컬 디비를 보고 싶은 석이였습니다...ㅠ.ㅠ 언젠간 dba 라고 명함에 함 적어보고 싶은데.....지금은 너무 초라하군요....

이 글에 대한 댓글이 총 11건 있습니다.

열이 선배님도 꼭 풀어주세요 ^-^ 배우도록 하겠습니다.

전 나름대로 다 풀었습니다.

비교함 해보죠 나중에 ^-^

석이님이 2005-06-08 04:35에 작성한 댓글입니다. Edit

헐.. 고민을 해봐야 할 듯한데요.

업무를 핑계삼아 여유있으면 바로 붙겠습니다.

여리님이 2005-06-08 09:03에 작성한 댓글입니다. Edit

주말을 곁들여 출장을 갔다왔는데, 재밌어보이는 문제가 올라와 있네요~ ^^*

 

담주 월요일 다시 출장.. -_-;;

일이 좀 쌓여 있지만, 이런 재밌는 문제를 그냥 넘어가면 안 되겠져.. 헤~

 

그럼, 나중에 시간을 내서 함 풀어보겠슴돠~~~

좋은 답안들 많이 나왔음 좋겠네여~

 

그럼, 이만~

길가는 나그네..님이 2005-06-08 15:43에 작성한 댓글입니다. Edit

음.. 이 바쁜 와중에 3-4시간을... 쩝.. -_-;;

 

trigger instead of insert / delete / update on view는 두 번째 만들어보네요.. 첫 번째는 프로젝트 실전 적용이었는데, 많은 응용가치가 있어 보이더라구요..

 

그럼, 이하 답변입니다..

출제자이신 석이님께서 채점도 해 주실려나 모르겠네요.. ^^;;

 

use tempdb
go

 

create table [OWNER] (
  [OwnerName] varchar(20) not null
, [Phone] varchar(14)
, [Street] varchar(200)
, [City] varchar(50)
, [State] varchar(20)
, [Zip] varchar(7)
)
create table [SERVICE] (
  [DateOfService] datetime not null
, [OwnerName] varchar(20) not null
, [Description] varchar(200)
, [AmountBilled] numeric(15)
, [AmountPaid] numeric(15)
, [DateOfPayment] datetime
)
create table [CHIP_DELIVERY] (
  [CustomerName] varchar(20) not null
, [DeliveryDate] datetime not null
, [LoadSize] int
, [AmountBilled] numeric(15)
, [AmountPaid] numeric(15)
, [DateOfPayment] datetime
)
go

 

alter table [OWNER]
  add constraint [pk_OWNER] primary key nonclustered ([OwnerName])
alter table [SERVICE]
  add constraint [pk_SERVICE] primary key nonclustered ([DateOfService], [OwnerName])
alter table [CHIP_DELIVERY]
  add constraint [pk_CHIP_DELIVERY] primary key nonclustered ([CustomerName], [DeliveryDate])

alter table [SERVICE]
  add constraint [fk_SERVICE] foreign key ([OwnerName]) references [OWNER] ([OwnerName])
                                                                                            on delete cascade on update cascade
alter table [CHIP_DELIVERY]
  add constraint [fk_CHIP_DELIVERY] foreign key ([CustomerName]) references [OWNER] ([OwnerName])
                                                                                            on delete cascade on update cascade

 


-- A. 테이블에 샘플 데이터를 넣고 출력하라.
insert into Owner values ('angel', '1414', 'angel''s street #1414', 'angel city', 'On the Sky', '0001414')

 

select * from Owner

 


-- B. 서비스 일정 계획을 관리하는 저장 프로시저를 작성하라.
--    프로시저는 모든 소유자 데이터와 DateOfService와 Description 데이터를 받는다.
--    만일 소유자가 이미 데이터베이스에 존재한다면, 기존의 소유자 데이터를 사용한다.
--    그렇지 않으면 OWNER 테이블의 한 행을 생성하라. 새로운 SERVICE 행을 생성하라.
--    프로시저를 작성하고 테스트하라.

if exists (select name from sysobjects where name = 'usp_insertService' and type = 'P')
  drop procedure usp_insertService
go
create procedure usp_insertService (
  @ownerName varchar(20)
, @phone varchar(14)
, @street varchar(200)
, @city varchar(50)
, @state varchar(20)
, @zip varchar(7)
, @dateOfService datetime
, @description varchar(200)
)
as
set nocount on
set transaction isolation level serializable

begin
  if (rtrim(isnull(@ownerName, '')) = '') or isnull(@dateOfService, '') = ''
    begin
      print 'please, check the necessary input informations !!!'
      return(1)
    end
  if not exists (select ownerName from OWNER where ownerName = @ownerName)
    begin
      insert into OWNER (ownerName, phone, street, city, state, zip)
        values (@ownerName, @phone, @street, @city, @state, @zip)
    end
  insert into SERVICE (dateOfService, ownerName, [description])
    values (@dateOfService, @ownerName, @description)
end
go

 

-- exec procedure 확인
exec usp_insertService 'wander', '01234', 'Street #2', 'City #2', 'State #2', '1234', '20050608', 'test by wanderer'
exec usp_insertService 'deleted', '01234', 'Street #3', 'City #3', 'State #3', '1234', '20050608', 'deleted'

 

select * from Owner
select * from Service

 

-- update cascade 확인
update Owner
  set ownerName = 'wanderer'
  where ownerName = 'wander'


select * from Owner
select * from Service

 

-- delete cascade 확인
delete from Owner
  where ownerName = 'deleted'


select * from Owner
select * from Service

 


-- C. 칩 배달을 위한 일정 계획을 관리하는 저장 프로시저를 작성하라.
--    프로시저는 모든 소유자 데이터와 DeliveryDate, LoadSize, Amount Billed를 받는다.
--    만일 이미 소유자가 데이터베이스에 있다면 소유자 데이터를 사용한다.
--    만일 소유자가 어떠한 체납 SERVICE 또는 CHIP_DELIVERY 레코드를 가지고 있다면 배달 계획을 잡지 마라.
--    대신 오류 메시지를 출력하라.
--    체납은 AmountBilled가 널값이 아닌 것을 의미하나 AmountPaid는 널값임을 의미한다.

if exists (select name from sysobjects where name = 'usp_insertDelivery' and type = 'P')
  drop procedure usp_insertDelivery
go
create procedure usp_insertDelivery (
  @ownerName varchar(20)
, @phone varchar(14)
, @street varchar(200)
, @city varchar(50)
, @state varchar(20)
, @zip varchar(7)
, @deliveryDate datetime
, @loadSize int
, @amountBilled numeric(15)
)
as
set nocount on
set transaction isolation level serializable

begin
  if (rtrim(isnull(@ownerName, '')) = '') or isnull(@deliveryDate, '') = ''
    begin
      print 'please, check the necessary input informations !!!'
      return(1)
    end
  if not exists (select ownerName from OWNER where ownerName = @ownerName)
    begin
      insert into OWNER (ownerName, phone, street, city, state, zip)
        values (@ownerName, @phone, @street, @city, @state, @zip)
    end
  if exists (select ownerName from SERVICE where ownerName = @ownerName
                                                                        and amountBilled is not null
                                                                        and amountPaid is null
                union
                select customerName from CHIP_DELIVERY where customerName = @ownerName
                                                                        and amountBilled is not null
                                                                        and amountPaid is null)
    begin
      print 'there exists the un-paid delivery records !!!'
      return(1)
    end
  insert into CHIP_DELIVERY (deliveryDate, customerName, loadSize, amountBilled)
    values (@deliveryDate, @ownerName, @loadSize, @amountBilled)
end
go

 

-- exec procedure 확인
exec usp_insertDelivery 'deliver', '01234', 'Street #4', 'City #4', 'State #4', '5678', '20050608', 100, 3000
exec usp_insertDelivery 'deleted', '01234', 'Street #5', 'City #5', 'State #5', '5678', '20050608', 200, 6000

 

select * from Owner
select * from Chip_Delivery

 

-- update cascade 확인
update Owner
  set ownerName = 'delivery'
  where ownerName = 'deliver'


select * from Owner
select * from Chip_Delivery

 

-- delete cascade 확인
delete from Owner
  where ownerName = 'deleted'


select * from Owner
select * from Chip_Delivery

 


-- D. 모든 OWNER와 SERVICE 데이터를 갖는 CustomerService라는 이름의 뷰를 생성하라.
--    CustomerService의 삽입을 위한 INSTEAD OF 트리거를 작성하라.
--    사용자는 모든 소유자 데이터와 DateOfService와 Description 데이터를 제공한다.
--    만일 소유자가 데이터베이스에 없다면, OWNER에 새로운 행을 삽입히라.
--    이 서비스와 관련하여 SERVICE 테이블에 행을 삽입하라. 트리거가 동작함을 입증하라.

if exists (select table_name from information_schema.views where table_name = 'CustomerService')
  drop view CustomerService
go
create view CustomerService (ownerName, phone, street, city, state, zip
                                              , dateOfService, [description], amountBilled, amountPaid, dateOfPayment)
as
select o.ownerName, phone, street, city, state, zip
        , dateOfService, [description], amountBilled, amountPaid, dateOfPayment
from Service s left join Owner o on s.ownerName = o.ownerName
go

if exists (select name from sysobjects where name = 'CustomerService_trg_ins' and type = 'TR')
  drop trigger CustomerService_trg_ins
go
create trigger CustomerService_trg_ins on CustomerService instead of insert
as
set nocount on
  if not exists (select o.ownerName from OWNER o inner join inserted i on o.ownerName = i.ownerName)
    begin
      insert into OWNER (ownerName, phone, street, city, state, zip)
        select ownerName, phone, street, city, state, zip from inserted
    end
  if not exists (select s.ownerName from SERVICE s inner join inserted i on (s.dateOfService = i.dateOfService
                                                                                                              and s.ownerName = i.ownerName))
    begin
      insert into SERVICE (dateOfService, ownerName, [description], amountBilled, amountPaid, dateOfPayment)
        select dateOfService, ownerName, [description], amountBilled, amountPaid, dateOfPayment from inserted
    end
go

 

select * from Owner
select * from Service
select * from CustomerService

 

-- trigger의 동작 확인
insert into CustomerService(ownerName, phone, street, city, state, zip
                                          , dateOfService, [description], amountBilled, amountPaid, dateOfPayment)
  values ('testView', '1414', 'angel''s street #1414', 'angel city', 'On the Sky', '0001414'
             , getdate(), 'test by instead of trigger on view', 100, 100000, getdate())

delete from OWNER
  where ownerName = 'testView'


--------------------------------------------------------
-- drop sample tables

drop table [SERVICE]
drop table [CHIP_DELIVERY]
drop table [OWNER]

 

길가는 나그네..님이 2005-06-08 18:07에 작성한 댓글입니다. Edit

경력이 느껴집니다.

^---^

전 마지막 문제가 틀린줄 알았어요 먼 뷰에다가 트리거를 만들어

이러면서....^-^ 이런게 되는군요

전 테이블 만들어서 넣어 봤는데 함 시도는 해볼걸 아깝네요...

제가 만든건 좀있다 공개 할께요....

 

한 수 멋지게 배웠습니다.

 

저두 3시간 반 걸렸습니다 ....전 이해도가 떨어지나 했는데

이해도는 비슷한가 봐요 ^---^ 안심안심....^-^

석이님이 2005-06-08 19:22에 작성한 댓글입니다.
이 댓글은 2005-06-08 19:27에 마지막으로 수정되었습니다. Edit

경력 1년이 안되는 지라 좀 모자란 점이 많습니다.

4번은 틀린답 그대로 ㅠ.ㅠ 올립니다.

나그네 님 100점 ^-^

 

-- ------------------------------------------------------------------------------
-- 한번에 수행하지 말고 단계별로 수행해야 합니다.
-- ------------------------------------------------------------------------------
-- 카탈로그 생성
-- ------------------------------------------------------------------------------
-- 해당 카탈로그가 있으면 지우고 새로고
-- 없으면 해당 데이터 베이스를 생성 합니다.
-- @database 에 생성하고자 하는 카탈로그 이름을 입력 합니다.
-- 유저의 기본 데이터 베이스를 현재 만든 데이터 베이스로 자동 설정
-- 현재의 유저는 sa 로 설정되어 있음
-- 알아서 변경하길 바람
-- ------------------------------------------------------------------------------
declare @database char(20)
declare @sql varchar(1000)
select @database = 'jin'
-- sysdatabases 에서 검색하는 것은 좋지 않으나 스크립트로 짜기 위해서 사용했음
-- sp_helpdb 를 이용해서 확인 할 수 있음
if exists(select name from master.dbo.sysdatabases where name =@database)
 begin
  print @database + ' 데이터 베이스 있음'
  print '데이터 베이스를 삭제하고 새로 만듭니다.'
  use master
  set @sql = 'drop database ' + @database
  exec (@sql)

  set @sql = 'create database ' + @database
  exec (@sql)
  print @database + '가 생성 되었습니다.'
  exec sp_defaultdb 'sa',@database
 end
else
 begin
  print @database + '없음 데이터 베이스를 생성합니다.'
  set @sql = 'create database ' + @database
  exec (@sql)
  print @database + '데이터 베이스가 생성 되었습니다.'
  exec sp_defaultdb 'sa',@database
 end


-- simple databse create
-- ------------------------------------------------------------------------------
-- create database jin2
-- ------------------------------------------------------------------------------

 

-- ------------------------------------------------------------------------------
-- 엔티티 생성
-- ------------------------------------------------------------------------------
-- 만든 데이터 베이스에서 작업하기 위해 use 문을 사용
-- 역시 테이블이 없으면 만든다.
-- 문제 1 : 아무런 제약 조건이 없는 테이블을 생성하라
-- entiry 1 Owner
-- entiry 2 Service
-- entiry 3 CHIP_DELIVERY
-- ------------------------------------------------------------------------------
use jin
go

-- ------------------------------------------------------------------------------
declare @tbl1 char(20)
declare @tbl2 char(20)
declare @tbl3 char(20)

set @tbl1 = 'Owner'
set @tbl2 = 'Service'
set @tbl3 = 'CHIP_DELIVERY'

if exists(select TABLE_NAME from information_schema.tables where (table_type='base table') and (table_name =@tbl1 or table_name  = @tbl2 or table_name =@tbl3  ))
 begin
  print '테이블이 존재 합니다. 확인후 수동생성 하세요 ^-^'
  print '다음은 해당 데이터 베이스에 존재 하는 테이블 이름 입니다.'
  select  table_catalog, table_name from information_schema.tables where table_type='base table'
 end
else
 begin
  print '테이블이 없습니다. 생성합니다.'

  create table Owner(
  OwnerName char(10) not null
  ,Phone char(13)
  ,Street varchar(50)
  ,City varchar(30)
  ,State varchar(30)
  ,Zip char(6)
  )

  print 'Owner 엔티티 생성됨'
  
  create table Service(
  DateOfService datetime
  ,OwnerName char(10) not null
  ,[Description] varchar(255)
  ,AmountBilled int
  ,AmountPaid int
  ,DateofPayment datetime
  )
  
  print 'Service 엔티티 생성됨'

  create table CHIP_DELIVERY(
  CustomerName char(10) not null
  ,DeliveryDate datetime
  ,LoadSize int
  ,AmountBilled int
  ,AmountPaid int
  )

  print 'chip_delivery 엔티티 생성됨'

 end

/* -- 엔티티 일괄 삭제시

drop table Service
drop table chip_delivery
drop table owner
*/


select * from information_schema.tables where table_name='owner'

-- ------------------------------------------------------------------------------
-- pk 설정 및 관계 형성
-- ------------------------------------------------------------------------------
-- sp_help owner
-- sp_help chip_delivery
-- sp_help Service
-- ------------------------------------------------------------------------------

ALTER TABLE Owner
       ADD PRIMARY KEY (OwnerName)
go

ALTER TABLE Service
 ADD FOREIGN KEY (OwnerName)
 REFERENCES Owner
 ON DELETE CASCADE
 ON UPDATE  CASCADE
go

ALTER TABLE CHIP_DELIVERY
 ADD FOREIGN KEY (CustomerName)
 REFERENCES Owner
 ON DELETE CASCADE
 ON UPDATE  CASCADE
go


-- ------------------------------------------------------------------------------
-- 문항 1
-- ------------------------------------------------------------------------------
-- Sample Data 삽입 및 데이터 확인
-- ------------------------------------------------------------------------------

-- Owner 데이터 삽입

insert into Owner (OwnerName, Phone, Street, City, State, Zip)
values ('문의자','000-0000-0000','AStreet','ACity','AState','000000')

insert into Owner (OwnerName, Phone, Street, City, State, Zip)
values ('문의자1','000-0000-0001','BStreet','BCity','BState','000000')

insert into Owner (OwnerName, Phone, Street, City, State, Zip)
values ('문의자2','000-0000-0002','CStreet','CCity','CState','000000')

insert into Owner (OwnerName, Phone, Street, City, State, Zip)
values ('문의자3','000-0000-0003','DStreet','DCity','DState','000000')

-- 삽입된 데이터의 확인
select OwnerName, Phone, Street, City, State, Zip from Owner


-- Service 데이터 삽입
set dateformat ymd
insert into Service
(DateOfService, OwnerName, [Description], AmountBilled, AmountPaid, DateofPayment)
values
(getdate(),'문의자','칩A를 주문합니다. -_- 이런거 넣으란거 맞는지'
,1000,0,'20050606')

insert into Service
(DateOfService, OwnerName, [Description], AmountBilled, AmountPaid, DateofPayment)
values
(getdate(),'문의자','칩B를 주문합니다. -_- 이런거 넣으란거 맞는지'
,1000,0,'20050606')

insert into Service
(DateOfService, OwnerName, [Description], AmountBilled, AmountPaid, DateofPayment)
values
(getdate(),'문의자','칩C를 주문합니다. -_- 이런거 넣으란거 맞는지'
,1000,0,'20050609')

-- 삽입된 데이터의 확인
select DateOfService, OwnerName, Description, AmountBilled, AmountPaid, DateofPayment
from dbo.Service

-- chip_delivery 데이터 삽입
insert into Chip_delivery
(CustomerName, DeliveryDate, LoadSize, AmountBilled, AmountPaid)
values
('문의자','20050607',1,1000,1000)

insert into Chip_delivery
(CustomerName, DeliveryDate, LoadSize, AmountBilled, AmountPaid)
values
('문의자1','20050607',1,1000,1000)

insert into Chip_delivery
(CustomerName, DeliveryDate, LoadSize, AmountBilled, AmountPaid)
values
('문의자2','20050607',1,1000,1000)


-- 삽입된 데이터의 확인
select CustomerName, DeliveryDate, LoadSize, AmountBilled, AmountPaid from chip_delivery


-- Service Entity 는 프로시져에 의해 삽입되어야 하므로 데이터 삭제.
-- chip_delivery 는 프로시져에 의해 관리 되어야 하므로 삭제
truncate table Service
truncate table chip_delivery


-- ------------------------------------------------------------------------------
-- 문항 2
-- ------------------------------------------------------------------------------
-- 서비스를 생성하는 프로시져 작성
-- 해당 프로시져는 owner 를 확인해 있으면 detail 정보만 Service 에 삽입하고 없으면
-- owner 에 새로운 행을 삽입한후 데이터를 입력한다.
-- ------------------------------------------------------------------------------


create proc USP_chkOwnerThenInputService
-- 몇월 몇일 누가
-- 숙제를 위해 만들었음
-- drop proc USP_chkOwnerThenInputService

(
 -- Owner 에 대한 정의
 @OwnerName char(10)
 ,@Phone char(13)
 ,@Street varchar(50)
 ,@City varchar(30)
 ,@State varchar(30)
 ,@Zip char(6)
 -- Service 에 대한 정의
 ,@DateOfService datetime
 ,@D varchar(255)
)
as

-- 에러 처리를 위한 변수 선언
declare @ERR int
set @ERR = 0
begin tran
 if exists(select OwnerName from Owner where OwnerName =@OwnerName)
  begin
   -- 소유자 존재
   insert into Service
   (DateOfService, OwnerName, [Description])
   values
   (@DateofService, @OwnerName,@D)
   set @ERR = @@error
  end
 else
  begin
   -- 소유자 없음 Owner entity 데이터 삽입 및 Service 데이터 삽입
   insert into Owner
   (OwnerName, Phone, Street, City, State, Zip)
   values
   (@OwnerName, @Phone,@Street,@City,@State,@zip)
   set @ERR = @@error

   print @OwnerName + @Phone + @Street + @City + @State + @zip

   insert into Service
   (DateOfService, OwnerName, [Description])
   values
   (@DateofService, @OwnerName,@D)
   set @ERR = @@error
  end

-- 에러가 있으면 롤백트랜 없으면 실행
if @ERR <> 0 rollback
else commit


-- Owner 에 데이터가 있는경우
exec USP_chkOwnerThenInputService
'문의자','000-0000-0000','StreetA','CityA','StateA','000000'
,'20050606','칩배달 서비스'

-- Owner 에는 들어가지 않고 Service 에만 들어가 있다.
-- 문제의 의도는 좋으나 모든 PK 인 OwnerName 은 적당하지 않다.
select * from Owner
select * from Service

--Owner 에 데이터가 없는 경우
exec USP_chkOwnerThenInputService
'문의자19','000-0000-0000','StreetA','CityA','StateA','000000'
,'20050606','칩배달 서비스'

select * from Owner
select * from service


-- ------------------------------------------------------------------------------
-- 3번 문제
-- ------------------------------------------------------------------------------
--
-- ------------------------------------------------------------------------------

create proc USP_checkDeferThenErrMessageOrInsertCD

(
 -- Owner 에 대한 정의
 @OwnerName char(10)
 ,@Phone char(13)
 ,@Street varchar(50)
 ,@City varchar(30)
 ,@State varchar(30)
 ,@Zip char(6)
 -- Chip Delivery 에 대한 정의
 ,@DeliveryDate char(8)
 ,@LoadSize int
 ,@AmountBilled int
)

-- drop proc USP_checkDeferThenErrMessageOrInsertCD

As

declare @ERR int
set @ERR = 0

-- 안시널값을 비교하기 위한 셋팅변환
set ansi_nulls off

begin tran
if exists (select OwnerName from OWNER where OwnerName = @OwnerName)
 begin
  set ansi_nulls off
  if (exists (select OwnerName from Service where AmountBilled > 0 and AmountPaid = null)) or
    (exists (select CustomerName from CHIP_DELIVERY where AmountBilled > 0 and AmountPaid = null))
   begin  
   print 'SERVICE 나 CHIP_DELIVERY 에 결제하지 않은 정보가 있습니다.'
    end
  else 
   begin
   insert into CHIP_DELIVERY (CustomerName, DeliveryDate, LoadSize, AmountBilled)
   values (@OwnerName,@DeliveryDate,@LoadSize,@AmountBilled)
   select @ERR = @@error   
   end
 end
else
 begin
  print 'OWNER 에 존재한지 않는 이름입니다.'
 end

 


if @ERR <> 0 rollback
else commit


exec USP_checkDeferThenErrMessageOrInsertCD
'문의자8','000-0000-0000','StreetA','CityA','StateA','000000',
'20050607',10,1000

select * from dbo.CHIP_DELIVERY

-- -------------------------------------------------------------------------------
-- 4 뷰의 생성
-- -------------------------------------------------------------------------------

create view View_OwnerAndService
as
select O.OwnerName, O.Phone, O.Street, O.City, O.State, O.Zip
,S.DateofService, S.Description, S.AmountBilled, S.AmountPaid, S.DateofPayment
from OWNER O left outer join
SERVICE S on O.OwnerName = S.OwnerName
 


-- drop view View_OwnerAndService
select * from View_OwnerAndService order by OwnerName


-- before trigger 가 적용될 테이블

create table tblOwnerAndService
(
OwnerName char(10)
, Phone char(13)
, Street varchar(50)
, City varchar(30)
, State varchar(30)
, Zip char(6)
, DateOfService datetime
, Description varchar(255)
, AmountBilled int
, AmountPaid int
, DateofPayment datetime
)

 

CREATE TRIGGER ITputTableTotal
ON SERVICE
INSTEAD OF INSERT
AS
BEGIN

declare @DateOfService datetime
, @OwnerName char(10)
, @Description varchar(255)

-- 없는 데이터를 찾아 넣기 위해서
, @Phone char (13)
, @Street varchar (50)
, @City varchar (30)
, @State varchar (30)
, @Zip char (6)

select
@DateOfService = DateOfService
,@OwnerName = OwnerName
,@Description = Description
from inserted

insert into  tblOwnerAndService (OwnerName, Phone, Street, City, State, Zip, DateOfService, Description, AmountBilled, AmountPaid, DateofPayment)
values (@OwnerName,'','','','','',@DateofService,@Description,0,0,0)

select  @Phone=Phone, @Street=Street, @City=City, @State=State, @Zip=Zip from Owner where OwnerName = @OwnerName
update  tblOwnerAndService set Phone = @Phone, Street = @Street, State = @State, Zip = @Zip
where OwnerName = @OwnerName and DateOfService = @DateOfService

END
GO

-- drop trigger ITputTableTotal


select * from dbo.tblOwnerAndService

석이님이 2005-06-09 02:00에 작성한 댓글입니다. Edit

100점은 너무 후하네요.. ^^*

 

Procedure 생성 시에는 역시 Transaction 처리의 범위(업무 단위)를 정하는 것이 가장 중요하겠죠.. 그런 다음은 Error에 대한 적절한 처리 기준을 정해서 처리하는 것이 중요합니다..

 

예전에 한 프로젝트에서 Procedure 내에서 발생한 Error는 Error 내역 테이블에 기록을 하도록 한 것을 본 적이 있습니다.. 논리적 에러라면 User에게 메시지를 날려주면 되지만, 그렇지 않은 에러라면 당연히 Log를 남겨야겠죠..

 

그럼..

 

p.s. 석이님, 경력에 비해 프로그램 깔끔하네요.. ^^*

 

길가는 나그네..님이 2005-06-09 10:47에 작성한 댓글입니다.
이 댓글은 2005-06-09 10:47에 마지막으로 수정되었습니다. Edit

정말 좋은 아이디어 입니다.

생각도 못했어요 에러이면 테이블에 에러로그를 만들자 ^-^

아 그럼 좋겠군요 확인 페이지 만들어서 매일 에러 나나 보던지

mail 로 자동으로 날아오게 스케줄 걸면 좋겠군요

아~ 좋습니다. 매일 매일 배우네요 ^-^

 

정말 감사합니다.

석이님이 2005-06-09 11:52에 작성한 댓글입니다. Edit

헐 손안되려고 했는데 그게 안되네요.

일단 B번까지 약 1시간 반을 넘어버렸네요.

흠.. 이것도 중독인가요? 여튼 C, D까지 하고 올려보겠습니다.

 

여리님이 2005-06-09 14:51에 작성한 댓글입니다. Edit

여리선배님 감사합니다.

^--------^

 

위에 나그네님 코드를 볼때는 그냥 업무 프로세스에 대해서는

생각해 보지 않았는데 선배님과 저 나그네님 코드를 모아서

최적 코드를 하나 만들어 보죠 정리는 출제자가 해야겠죠?

 

미션에 맞는 일을 했는지 철저히 분석해서 채점 함 들어가보겠습니다.

^-^ 채점하다 틀릴 수 있습니다. 제가 뭐 천재도 아니고 답도 없는데

할 수 있겠냐만은 선배님들이 해 놓은거 보고 한번 해보고 선배님들이

또 지적해 주시면 달갑게 또 배우겠습니다.

 

두분 너무나 감사합니다.

 

다른 분들도 도전 해 보세요 쉬운 문제만은 아니거든요 ^-^

이해는 가는데 실제로 적용시키면서 코드 스타일을 배울 수 있는

좋은 기회가 될것도 같습니다.

 

그럼 이만 줄입니다.

 

석이님이 2005-06-09 18:24에 작성한 댓글입니다. Edit

1번에는 이렇게 하고 싶네요.
일단 DataType은 제가 아는 걸로 만 했습니다. ^^

(char이게 그겁니다.)
CREATE TABLE Owner (
 OwnerName char (18)  NOT NULL ,
 Phone char (18)  NOT NULL ,
 Street char (18)  NOT NULL ,
 City char (18)  NOT NULL ,
 State char (18)  NOT NULL ,
 Zip char (18)  NOT NULL
)
GO

CREATE TABLE Service (
 DateofService datetime  NOT NULL ,
 Description char (18)  NOT NULL ,
 AmountBilled char (18)  NOT NULL ,
 AmountPaid char (18)  NOT NULL ,
 DateofPayment datetime  NOT NULL ,
 OwnerName char (18)  NOT NULL
)
GO


CREATE TABLE Chip_Delivery (
 CustomerName char (18)  NOT NULL ,
 DeliveryDate datetime  NOT NULL ,
 LoadSize char (18)  ,
 AmountBilled char (18)  ,
 AmountPaid char (18)  ,
 DateofPayment datetime  NOT NULL ,
 OwnerName char (18)  NULL
)
GO

 


ALTER TABLE Chip_Delivery ADD
  PRIMARY KEY  NONCLUSTERED  (CustomerName)  
GO

ALTER TABLE Owner ADD
  PRIMARY KEY  NONCLUSTERED
 (OwnerName)  
GO

ALTER TABLE Service ADD
  PRIMARY KEY  NONCLUSTERED
 (OwnerName)  
GO

ALTER TABLE Chip_Delivery ADD
 CONSTRAINT FK__Chip_Deli__Owner__023D5A04 FOREIGN KEY
 (OwnerName) REFERENCES Owner (OwnerName)
  ON DELETE CASCADE  ON UPDATE CASCADE
GO

ALTER TABLE Service ADD
 CONSTRAINT FK__Service__OwnerNa__03317E3D FOREIGN KEY
 (OwnerName) REFERENCES Owner (OwnerName)
  ON DELETE CASCADE  ON UPDATE CASCADE
GO


A. 데이터의 삽입..
 참고했슴.. 게으름으로.. 데이터 짤리는 건 적당히 수정하구요..

/*
B. 서비스 일정 계획을 관리하는 저장 프로시저를 작성하라.
프로시저는 모든 소유자 데이터와 DateOfService와 Description 데이터를 받는다.
만일 소유자가 이미 데이터베이스에 존재한다면,
기존의 소유자 데이터를 사용한다.
그렇지 않으면 OWNER 테이블의 한 행을 생성하라.
새로운 SERVICE 행을 생성하라. 프로시저를 작성하고 테스트하라.
*/

select * from service
create proc usp_seviceSch (
  @OwnerName char(18)
 , @Phone char(18)
 , @Street char(18)
 , @City char(18)
 , @State char(18)
 , @zip char(18)
 , @DateOfService dateTime
 , @Description char(18)
)
As
set nocount on
IF  Not exists (select OwnerName from Owner where OwnerName = @OwnerName)
 Begin
  insert into Owner values (@OwnerName, @Phone, @Street, @City, @State, @zip)
 End
Else
 Begin
  insert into Service (DateOfService, [Description], OwnerName) values (@DateOfService, @Description, @OwnerName)
 End
 
set nocount off 


/*
C. 칩 배달을 위한 일정 계획을 관리하는 저장 프로시저를 작성하라.
프로시저는 모든 소유자 데이터와 DeliveryDate, LoadSize, Amount Billed를 받는다.
만일 이미 소유자가 데이터베이스에 있다면 소유자 데이터를 사용한다.
만일 소유자가 어떠한 체납 SERVICE 또는 CHIP_DELIVERY 레코드를 가지고 있다면 배달 계획을 잡지 마라.
대신 오류 메시지를 출력하라. 체납은 AmountBilled가 널값이 아닌 것을 의미하나 AmountPaid는 널값임을 의미한다.
*/


create proc usp_chipD (
 @OwnerName as char(18)
, @Phone as char(18)
,  @Street as char(18)
,  @City as char(18)
, @State as char(18)
, @zip as char(18)
, @deliveryDate as datetime
, @LoadSize as char(18)
, @AmountBilled as char(18)
)

As
Declare
 @err_No as int

set @err_no = 0

Begin
 IF Not Exists (Select  OwnerName  From Serverce where OwnerName = @OwnerName  and (AmountBilled is not Null and AmountPaid is null))
 Begin
  IF Not Exists (Select CustomerName From chip_delivery where CustomerName = @OwnerName)
  Begin
   set @err_no = 0
  End
  Else
   set @err_no = 1 --Chip 배달건수가 이미 있슴
 End
 Else
  set @err_no = 2 --체납?

                 

if @err_no = 0
Begin
 insert into CHIP_DELIVERY (customerName, deliveryDate, LoadSize, AmountBilled)
     values (@OwnerName, @deliveryDate, @LoadSize, @AmountBilled)

 Print 'Input Chip_Delivery Success!'
End 
Else
 If @err_no = 1
  Print  'Input Failed:::not Chip Delivery!!!'
 else
  Print 'Input Failed ::: Not Paid'

 

 


/*
D. 모든 OWNER와 SERVICE 데이터를 갖는 CustomerService라는 이름의 뷰를 생성하라.
CustomerService의 삽입을 위한 INSTEAD OF 트리거를 작성하라.
사용자는 모든 소유자 데이터와 DateOfService와 Description 데이터를 제공한다.
만일 소유자가 데이터베이스에 없다면, OWNER에 새로운 행을 삽입히라.
이 서비스와 관련하여 SERVICE 테이블에 행을 삽입하라. 트리거가 동작함을 입증하라.
*/

--select * from Chip_Delivery
select * from Service
select * from Owner

create view CustomerService (
 OwnerName, Phone, Street, City, State, Zip, DateOfService, [Description], AmountBilled, AmountPaid, DateOfPayment
)
As

Select a.OwnerName, Phone, Street, City, State, zip, DateOfService, [Description], AmountBilled, AmountPaid, DateOfPayment
 From Owner a
  Inner Join Service b On a.OwnerName = b.OwnerName

 

create trigger trg_CustomerService_ins
 on CustomerService instead of insert
as
  if not exists (select a.OwnerName from OWNER a inner join inserted x on a.OwnerName = x.OwnerName)
    begin
      insert into OWNER (OwnerName, Phone, Street, City, State, Zip)
        select ownerName, phone, street, city, state, zip from inserted
    end
  if not exists (select a.OwnerName from SERVICE a inner join inserted x on (a.OwnerName = x.OwnerName))
    begin
      insert into SERVICE (dateOfService, ownerName, [description], amountBilled, amountPaid, dateOfPayment)
        select dateOfService, ownerName, [description], amountBilled, amountPaid, dateOfPayment from inserted
    end

 

 

늦었지만 나름대로 열심히 만들어봤습니다.

없는 실력과 업무를 핑계삼계습니다.

 

생각의 틈을 줘야 하는 것들이 많아 한번에 가려고 하니 그렇게 된거 이해하시고요.

 

늦은 것에 대한 것도 점수에 반영해주시기 바랍니다.

그럼 좋은 하루 되십시요 ^^

여리님이 2005-06-10 12:47에 작성한 댓글입니다.
이 댓글은 2005-06-10 13:24에 마지막으로 수정되었습니다. Edit
[Top]
No.
제목
작성자
작성일
조회
2015데이터 베이스가 홀라당 날라 갔어요 ㅠ.ㅠ [1]
nuno
2005-06-09
3181
2013선택월의 주만 구할 수 있는 스크립트 급구합니다. [5]
한스
2005-06-08
3345
2012[접속에러18456]접속에러 원인 좀알려줘요 [1]
이지송
2005-06-08
6379
2011데이터 베이스 문제 입니다. 한번 풀어보세요 [11]
석이
2005-06-08
7699
2010쿼리를 어떻게 맹그러야할지... [4]
준팔이
2005-06-07
2804
2009사용자별 게시판 생성시... [2]
조나단
2005-06-07
2472
2008스케줄, 링크드서버관련 오류입니다. 답글 좀 주세요 ㅜㅜ
손님
2005-06-07
3999
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2024 DSN, All rights reserved.
작업시간: 0.018초, 이곳 서비스는
	PostgreSQL v16.2로 자료를 관리합니다