GSI

> Microsoft SQL Server Management Studio 를 실행하여, 원하는 DB의 "속성" 을 누른다.

> "옵션" 페이지에서 "복구 모델" 을 "전체" 에서 "단순" 으로 변경하고 "확인" 을 누른다.

> 다시 원하는 DB의 "태스크" > "축소" > "데이터베이스" 를 선택한다.

> "데이터베이스 축소" 창이 뜨는데, "확인"을 선택하여 축소 작업을 수행한다.

> 해당 DB의 로그 파일의 크기가 줄어들었음을 확인한다.

> 다시 DB의 "속성"의 "복구 모델"을 "단순"에서 "전체"로 돌려 놓는다.


-끝-

Posted by gsi
:

가령 22시 30분 19초의 정보가 문자열로 왔을 경우

해당 문자열에 (:) 처리를 해주지 않으면 시간값으로 처리를 할수가 없다.

그래서 아래와 같이 구문을 통해서 처리가 가능하다.


STUFF(STUFF('223019', 3, 0, ':'), 6, 0, ':'))


>> 223019 -> 22:30:19


Posted by gsi
:

SELECT REPLACE(CONVERT(varchar(max),textvalue), Substring(textvalue,Len(textvalue)-1,2),'**')
from TBL_TEST_DB

textvalue의 값이 12345 라고 하면 123** 로 치환한다.
Posted by gsi
:


구글이라던지 이곳저곳 찾아 보면 상당히 많은 예제가 나오는거 같다.
GsiClip을 제작중에 DB에 이미지를 데이터로 추가 해야 하는 부분에
단위 테스트에 사용한 소스 코드임. (테스트 수행)

        private void button1_Click(object sender, EventArgs e)
        {
            // 이미지를 DB로 저장한다.
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                ImageSave(openFileDialog1.FileName);

                MessageBox.Show("저장완료");
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            // 이미지를 DB에서 로드한다.
            dsImageTableAdapters.Test1TableAdapter adapter =
                new ImageSaveDB.dsImageTableAdapters.Test1TableAdapter();
            dsImage.Test1DataTable table =
                new dsImage.Test1DataTable();

            adapter.Fill(table);

            if (table.Count > 0)
            {
                pictureBox1.Image = byteArrayToImage(table[0].Content2);
            }
        }

        public Image byteArrayToImage(byte[] byteArrayIn)
        {
            MemoryStream ms = new MemoryStream(byteArrayIn);
            Image returnImage = Image.FromStream(ms);
            return returnImage;
        }

        byte[] ReadFile(string sPath)
        {
            byte[] data = null;

            //
            FileInfo fInfo = new FileInfo(sPath);
            long numBytes = fInfo.Length;
            //
            FileStream fStream = new FileStream(sPath, FileMode.Open, FileAccess.Read);
            //
            BinaryReader br = new BinaryReader(fStream);
            //
            data = br.ReadBytes((int)numBytes);

            return data;
        }

        private void ImageSave(string filename)
        {
            byte[] imageData = ReadFile(filename);

            //
            dsImageTableAdapters.Test1TableAdapter adapter =
                new ImageSaveDB.dsImageTableAdapters.Test1TableAdapter();

            adapter.Insert(imageData);
        }

Posted by gsi
:

> 테이블 합치는 방법 : 테이블 + 2009 + 09
> 테이블이 존재 하지 않으면 테이블을 생성한다.

---------------------------------------------------------------------------------------
DECLARE @curDateString varchar(100)
DECLARE @tableCount int
DECLARE @sql nvarchar(4000)

-- 현재 시간에서 년, 월을 가져온다.
SET @curDateString = 'TBL_SERVICE_LOG_'
     + convert(varchar(30), year(GetDate()))
     + REPLICATE('0', 2 - len(month(GetDate()))) + convert(varchar(30), month(GetDate()))
--print @curDateString

-- 테이블 존재 하는지 개수를 가져온다.
select @tableCount = count(*)
from sysobjects
where xtype='U' and
name = @curDateString

--print @tableCount

-- 테이블이 존재 하지 않으면 테이블을 생성한다.
IF @tableCount != 1
BEGIN
 SET @sql = N'CREATE TABLE ' + @curDateString + N' (' +
 N'[OrderNo] [int] NULL,' + 
 ...................생략...............
 N'[OriginTelNo] [varchar](50) NULL' +
 N');'
 EXEC(@sql)
END
--ELSE
--BEGIN
 --print '테이블 존재함'
--END

Posted by gsi
:


-- 하루전 오후 12:00 시 구하는 방법
DECLARE @prevDate varchar(100)
DECLARE @prevDateTime DateTime
SET @prevDate = convert(varchar, getDate(), 112)-1
SET @prevDate = @prevDate
PRINT @prevDate
SET @prevDateTime = cast(@prevDate as DateTime)
PRINT @prevDateTime
PRINT DATEADD(hh, 12, @prevDateTime)

>> 위에걸 최적화 하면 한줄로 되네요. ^^
DATEADD(HOUR,12, CONVERT(DATETIME, CONVERT(CHAR(10), DATEADD(DAY,-1,GETDATE()) ,120)))
Posted by gsi
:

insert  into aaa.dbo.aa select * from bbb.dbo.bb;
-- 이걸 사용하게 되면 다른 DB의 같은 테이블 구조를 가지고 있을때 내용을 복사할 수 있다.

Posted by gsi
:


DROP TABLE #MyTempTable; --임시테이블을 만든다.
-- CTE 구조로 해서 원하는 내용을 뽑아 온다.
with empCTE(
 _idx,
 _uid,
 _puid)
as
(
 -- boss only
 select idx, uid, puid
 from userList_tmp
 where uid = 'test1' and grade = '2' --최초 탐색 시점

 union all

 select aa.idx, aa.uid, aa.puid
 from userList_tmp as aa inner join empCTE as bb
 on aa.puid = bb._uid
 --where bb.level < 3
)
select _idx into #MyTempTable from empCTE --임시테이블로 복사
GO
-- 임시 테이블의 내용을 원본 테이블에서 삭제
delete from userList_tmp where idx in (select * from #MyTempTable)  제

Posted by gsi
:



위쪽의 쿼리 결과 리스트에서 보면 uid, puid, grade 등의 조직도를 구성할 수 있는 정보가 존재 할때
아래와 같은 결과를 만들어 낼 수 있다.

[쿼리예]
with empCTE(empUid, mgrName, dept, level)
as
(
 -- 보스
 select uid, puid, grade, 0
  from userList
  where puid is null and grade = '0'
 union all
-- 나머지 grade를 포함한 내용
 select aa.uid, aa.puid, aa.grade, bb.level+1
  from userList as aa inner join empCTE as bb
  on aa.puid = bb.empUid
 where bb.level < 3  -- 이 코드가 없어지면 모든 grade에 대해서 출력이 된다. 즉, grade를 제한할때 사용
)
select replicate('ㄴ', level) + empUid as uid, dept from empCTE order by empUid, level
Posted by gsi
:




여기서 userList의 테이블과  calcInfo 의 테이블에 대해서 합치는 쿼리를 구성해 볼려구 한다.

두개의 테이블의 내용은 아래와 같다.
[userList]

[calcInfo]


두개의 테이블을 조인해야 하는데 문제는
calcInfo의 uid별 income, outcome을 sum을 해야 하는게 관건이였다.
쿼리는 잘 모르다 보니 이런 구문은 항상 아리송하다 ^^

아래는 결과 쿼리다.
select aa.uid, aa.puid, aa.gameCash, bb.income, bb.outcome from userList as aa
inner join
(select uid, sum(income) as income, sum(outcome) as outcome from calcInfo as bb group by uid)
bb on aa.uid = bb.uid

[출력화면]

Posted by gsi
:


declare @idx int
declare @account varchar(20)
declare @nickname varchar(20)
declare @account2 varchar(20)
declare @nickname2 varchar(20)

set @idx = 0
set @account = 'test'
set @nickname = 'Dummy'

while (1=1)
begin
 if @idx > 9999 break;
 set @account2 = @account + convert(varchar(4), @idx)
 set @nickname2 = @nickname + convert(varchar(4), @idx)
 print @idx
 print @account2 + @nickname2
 INSERT INTO [NDT].[dbo].[USERACCOUNT]
           ([ACCOUNT]
           ,[PASSWORD]
           ,[NICKNAME]
           ,[MONEY]
           ,[LOGINSTATE])
     VALUES
           (@account2
           ,'1'
           ,@nickname2
           ,0
           ,0)
 set @idx = @idx + 1
end

Posted by gsi
:


게시판을 생성하다 보면 게시물의 내용에 특수문자가 들어 가게 되는데
그것 자체가 쿼리 문의 실패를 가져 오게 된다.

그래서 쿼리문 자체에서 치환을 해주는 형태로 진행하고,
웹에서 데이터를 가져온 다음에 변환해 주는 것으로 작업을 마무리 해봤다.

--DB에서 값을 변환하는 구문
USE [MarineX]
GO
/****** 개체:  StoredProcedure [dbo].[sp_ReplyInsert]    스크립트 날짜: 04/24/2009 14:55:11 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[sp_ReplyInsert]
(
 @TableName varchar(100),
 @Name varchar(25),
 @Email varchar(100),
 @Title varchar(150),
 @PostIP varchar(15),
 @Content varchar(1000),
 @Password varchar(20),
 @Encoding varchar(10),
 @Homepage varchar(100),
 @Ref varchar(10),
 @Step varchar(10),
 @RefOrder varchar(10)
)
AS
 SET NOCOUNT OFF;
 declare @sql varchar(500)
 set @sql= 'INSERT INTO ' + @TableName +
 '([Name], [Email], [Title], [PostIP], [Content], [Password], [Encoding], [Homepage], [Ref], [Step], [RefOrder]) ' +
 'VALUES ( ''' +
  @Name+''', '''+
  @Email+''', '''+
  @Title+''', '''+
  @PostIP+''', '''+
  REPLACE(@Content, char(39), '%#39;')+''', '''+
  @Password+''', '''+
  @Encoding+''', '''+
  @Homepage+''', '''+
  @Ref+''', '''+
  @Step+''', '''+
  @RefOrder+ ''' )';
 exec(@sql)

웹에서는 반대로 진행한다.
if (list[0].Encoding == ReplyBoard.EncodingType.Text)
{
    tmpContent =
        list[0].Content.ToString().Replace("&", "&amp;").Replace("<", "&lt;").Replace(">", "&gt;").Replace("\r\n", "<br>").Replace("%#39;", "'");
}

우선 이렇게 해서 다른 문제점이 생기는지 파악해 보자.
Posted by gsi
:


asp.net 을 하면서 게시판을 제작하다 보면
정말 초보자 수준에서 보게 되면, 게시판 같은 경우
같은 테이블을 사용해야 하는 상황이 생기는데, 이런 경우 저장 프로시저를 각 테이블 별로
제작 하게 되면 작업사항도 번거로워 지는걸 발견해서
저장 프로시저를 동적 테이블을 구성해 볼려고 했다.

쩝.. 세상 프로그램은 쉬운게 없더라..

가장 쉽게 저장 프로시저를 구성하면 아래와 같아 진다.
ALTER PROCEDURE [dbo].[sp_ReplyListNum]
(
 @Num int
)
AS
 SET NOCOUNT ON;
 SELECT * FROM dbo.Reply Where Num=@Num

이런 경우에 쉽게 생각 하면 dbo.@TableName 이런 식의 표현이 가능할 줄 알았다.
하지만 이렇게 할 경우 허용이 되지 않는 것을 발견하였다.

그래서 이런 경우 exec()를 사용해서 해당 테이블을 만든 다음에 적용해야 한다.
declare @sql varchar(200)
set @sql='Select * From Reply Where ' + @strSearchField + ' Like ''%' + @strSearchQuery + '%'' Order By Num Desc';
exec(@sql)

하지만 이렇게 했을때 결과는 제대로 나오지만 asp.net에서 데이터 셋을 연동하게 되면
제대로 표현이 안되는 경우가 있다.

하나의 예를 보면..
ALTER PROCEDURE [dbo].[sp_ReplyListNum]
(
 @Num int
)
AS
 SET NOCOUNT ON;
 SELECT * FROM dbo.Reply Where Num=@Num

순수하게 위의 코드를 수행하게 되면  * 부분에서 Reply 의 모든 컬럼을 리턴 시킨다.
그래서 데이터 셋에 서버탐색기를 통해서 저장 프로시저를 드래그앤 드롭을 하게 되면
아래와 같은 내용으로 적용이 된다.

이런 식의 테이블과 테이블 어뎁트가 같이 구성이 된다.

하지만 문제는 exec()를 실행하게 되면 결과는 int 형태로만 나오기 때문에,
테이블 형태로 받아야 할때가 필요 하게 되더라
그래서 찾아보다 보니 sp_executesql 이게 필요하다는 것을 알게 되었다.

아래 부분은 해당 쿼리를 보내고 나서, 보낸 내용중에서 필요한 컬럼만 리턴해 보기 위한 쿼리 내용입니다.
ALTER PROCEDURE [dbo].[sp_ReplyList]
 @TableName varchar(100)
AS
 SET NOCOUNT ON;
 declare @sql nvarchar(2000)
 declare @v_Num int
 declare @v_Name varchar(25)
 declare @v_Email varchar(100)
 declare @v_Title varchar(150)
 declare @v_PostDate datetime
 declare @v_PostIP varchar(15)
 declare @v_Content varchar(1000)
 declare @v_Password varchar(20)
 declare @v_ReadCount int
 declare @v_Encoding varchar(10)
 declare @v_Homepage varchar(100)
 declare @v_ModifyDate datetime
 declare @v_ModifyIP varchar(15)
 declare @v_Ref int
 declare @v_Step int
 declare @v_RefOrder int
 set @sql='Select @v_Num=Num, @v_Name=Name, @v_Email=Email, @v_Title=Title, @v_PostDate=PostDate, @v_PostIP=PostIP, @v_Content=Content, @v_Password=Password, @v_ReadCount=ReadCount, @v_Encoding=Encoding, @v_Homepage=Homepage, @v_ModifyDate=ModifyDate, @v_ModifyIP=ModifyIP, @v_Ref=Ref, @v_Step=Step, @v_RefOrder=RefOrder From ' + @TableName + ' Order by Num Desc'
 --exec(@sql)
 exec sp_executesql
  @sql,
  N'@v_Num int out, @v_Name varchar(25) out,
  @v_Email varchar(100) out, @v_Title varchar(150) out, @v_PostDate datetime out,
  @v_PostIP varchar(15) out, @v_Content text out, @v_Password varchar(20) out,
  @v_ReadCount int out, @v_encoding varchar(10) out, @v_Homepage varchar(100) out,
  @v_ModifyDate datetime out, @v_ModifyIP varchar(15) out,
  @v_Ref int out, @v_Step int out, @v_RefOrder int out',
  @v_Num out,
  @v_Name out,
  @v_Email out,
  @v_Title out,
  @v_PostDate out,
  @v_PostIP out,
  @v_Content out,
  @v_Password out,
  @v_ReadCount out,
  @v_Encoding out,
  @v_Homepage out,
  @v_ModifyDate out,
  @v_ModifyIP out,
  @v_Ref out,
  @v_Step out,
  @v_RefOrder out
-- 위에서 수행한 정보를 select를 통해서 리턴 시켜야 한다.
 select @v_Num as Num,
   @v_Name as Name,
   @v_Email as Email,
   @v_Title as Title,
   @v_PostDate as PostDate,
   @v_PostIP as PostIP,
   @v_Content as Content,
   @v_Password as Password,
   @v_Readcount as ReadCount,
   @v_Encoding as Encoding,
   @v_Homepage as Homepage,
   @v_ModifyDate as ModifyDate,
   @v_ModifyIP as ModifyIP,
   @v_Ref as Ref,
   @v_Step as Step,
   @v_RefOrder as RefOrder
Posted by gsi
:

A의 테이블에 idx라는 자동증가 컬럼이 있다고 한다면
모든 컬럼 내용을 다 복사 하지는 못한다.
그래서 아래와 같이 추가할 컬럼을 지정한 후에 복사를 해야 한다.

INSERT INTO userList
           ([uid]
           ,[passwd]
           ,[name]
           ,[phone]
           ,[email]
           ,[jumin1]
           ,[jumin2]
           ,[zipcode1]
           ,[zipcode2]
           ,[address1]
           ,[address2]
           ,[regdate]
           ,[level]
           ,[exp]
           ,[cash]
           ,[gem]
           ,[IsBlocked]
           ,[IsGameUser]
           ,[gameScore]
           ,[gameCash]
           ,[grade])
select a.uid, a.passwd, a.name, a.phone, a.email,
  a.jumin1, a.jumin2, a.zipcode1, a.zipcode2, a.address1, a.address2,
  a.regdate, a.level, a.exp, a.cash, a.gem, a.IsBlocked, a.IsGameUser,
  a.gameScore, a.gameCash, a.grade

from leave_userList a
where idx=3
Posted by gsi
:


두개의 테이블이 있다.

GalleryBoard2 에는 게시물이 저장된다.
그리고 GalleryBoard2File 에는 게시물에서 첨부이미지가 저장된다.
idx - imgIDX 를 통해서 해당 게시물의 이미지 파일을 연결한다.

이때 GalleryBoard2의 해당 게시물을 삭제 하게 될때
GalleryBoard2File의 내용도 같이 삭제를 해야 한다.
하지만, 두개의 테이블을 따로따로 삭제할 경우 좀 번거롭고 문제가 생기기 마련이다.
그래서 관계를 위의 이미지와 같이 형성하고 GalleryBoard2를 삭제 하면 GalleryBoard2File의 내용도 같이 포함된다.

간단하게 설명하면
1. MSSql 2005에서 데이터베이스 다이어그램을 새로 생성한다.
2. GalleryBoard2, BalleryBoard2File을 두개 추가한다.
3. 두개의 테이블에서 GalleryBoard2의 idx GalleryBoard2FileimgIDX를 드래그해서 연결한다.
4. 연결후에 속성을 아래와 같이 변경한다.
  - 기본으로 설정된 속성은 그대로 둔다.
  - INSERT 및 UPDATE 사양 에서 삭제 규칙 을 "계단식 배열"로 정한다.
    (사실 여기에 몇개 설정값이 있지만, 잘 모른다. 혹시 아신다면 코멘트 부탁해요)
5. 이게 정상적으로 되었다면 삭제처리를 해보기 바란다. 자동으로 삭제가 되니 코딩도 편해진다.
Posted by gsi
: