반응형

SQL Server 에서 오픈쿼리 사용 시 8000자를 넘어가면 실행이 불가능하다.

 

오픈쿼리 특성 상 테이블변수를 사용하지 못하기에 WHERE 절에서 IN 으로 조회하게 되는데

대상이 많아지면 8000자를 넘는일이 자주 발생한다.

 

예제

DECLARE @V_TABLE TABLE
(
	ORD_NO INT ,
	ORD_NAME VARCHAR(30)
)

DECLARE @QUERY NVARCHAR(MAX)
DECLARE @MULTI_ORD_NO NVARCHAR(MAX)


-- 1. 대상 테이블로 받을 때 행 별 콤마 추가
-- ex) 1,2,3
SELECT @MULTI_ORD_NO = STRING_AGG(CAST(ORD_NO AS NVARCHAR(MAX)), ',') FROM (SELECT ORD_NO FROM @V_TABLE) A

SET @QUERY = N'
SELECT 1 FROM A WHERE KEY IN ('+ @MULTI_ORD_NO +')
'

EXECUTE (@QUERY) AT LINKED_SERVER

 

참고로 STRING_AGG 할 때 꼭 NVARCHAR(MAX)로 캐스팅해서 써야 한다.

반응형
반응형

 

MS SQL ORDER BY 조건

 

프로그래밍시 정렬을 해도되지만

  

쿼리단계에서 ORDER BY CASE 문을 이용한 정렬 방법이다

 

다음과 같은 테이블이 있을때

 

USER_ST 3, 2, 1, 4 로 정렬하려면

 

SELECT * FROM USERS
ORDER BY 
  CASE 
    WHEN USER_ST = 3 THEN 0 
	WHEN USER_ST = 2 THEN 1
	WHEN USER_ST = 1 THEN 3
	WHEN USER_ST = 4 THEN 4
	ELSE 99
  END ASC

위와 같이 CASE 를 사용하여 임의로 순서를 지정해주면 된다.

 

 

 

SELECT * FROM USERS
ORDER BY 
  CASE 
    WHEN USER_ST = 3 THEN 0 
	WHEN USER_ST = 2 THEN 1
	WHEN USER_ST = 1 THEN 3
	WHEN USER_ST = 4 THEN 4
	ELSE 99
  END ASC,
  CASE 
    WHEN USER_ID = 'PARK' THEN 0
	ELSE 1
  END ASC

위와 같이 CASE 문을 여러개 중복 사용하여 정렬도 가능하다.

반응형
반응형

SQL SERVER AFTER 트리거 사용 시

특정 컬럼 업데이트를 감지하여 작동하는 쿼리 예제 입니다.

 

흔히 이력 정보를 저장할 때, 특정 컬럼의 값이 변하는지 감지하고

감지하는 컬럼의 값이 변할때만 작동하도록 해야하는 상황이 많습니다.

 

예제.

사용자 테이블과 사용자 이력 테이블 트리거 작성

 

트리거를 가지고 있는 USERS 테이블 

*[USER_ID], [USER_NM], [USER_PWD], [USER_ST], [EDT_DT]

 

USERS 테이블의 이력을 저장할 USERS_HIS 테이블

*[USER_ID], *[HIS_IDX], [USER_NM], [USER_ST], [EDT_DT]

 

목표는 USERS 테이블의 [USER_ST] (유저 상태)컬럼 값이 변할 때 이력을 저장하는 것 입니다.

[USER_ST]가 변할 때 USERS_HIS 테이블에 데이터를 삽입하도록 트리거를 작성하면 됩니다.

 

예제는 다음과 같습니다.

 

 

 

 

트리거 INSERTED 와 DELTED 시에는 그냥 이력을 삽입하면되니 UPDATED만 예제로 작성하겠습니다.

 

1. 트리거 쿼리문

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:		davi
-- Create date: 210323
-- Description:	Insert history when [USERS]'s USER_ST updated
-- =============================================
CREATE TRIGGER [dbo].[TRG_USERS_UPDATED]
   ON  [dbo].[USERS]
   AFTER INSERT,DELETE,UPDATE
AS 
BEGIN
	-- SET NOCOUNT ON added to prevent extra result sets from
	-- interfering with SELECT statements.

	SET NOCOUNT ON;
    --USER 테이블에서 이력을 저장할 컬럼 변수 생성
	DECLARE
	@USER_ID varchar(20),
	@HIS_IDX int,
	@USER_NM varchar(10),
	@USER_ST	char(1),
	@EDT_DT datetime

		--I : INSERTED
		--U : UPDATED
		--D : DELETED
		DECLARE @TRG_ACTION char(1)

		--INSERTED
		SET @TRG_ACTION = 'I'

		--U : UPDATED
		--D : DELETED
		IF EXISTS(SELECT * FROM deleted)
		  BEGIN
		    SET @TRG_ACTION = (CASE WHEN EXISTS (SELECT * FROM inserted) THEN 'U' ELSE 'D' END)
		  END


		  --UPDATED 만 작성
		  IF @TRG_ACTION = 'U'
		   BEGIN
			SELECT 
			  @USER_ID = INS.USER_ID, @USER_NM = INS.USER_NM, @USER_ST = INS.USER_ST, @EDT_DT = INS.EDT_DT
			FROM DELETED DEL
			JOIN INSERTED INS ON DEL.USER_ID = INS.USER_ID --PK로 JOIN
			WHERE 
			DEL.USER_ID = INS.USER_ID AND
			DEL.USER_ST != INS.USER_ST --컬럼 값이 다르면 USER_ST가 변경되었을때이다.  
		   END

		   IF(@USER_ID IS NOT NULL)
		     BEGIN
			   --USERS_HIS 테이블에서 해당 USER_ID의 변경 순서 +1
			   SELECT @HIS_IDX = ISNULL(MAX(HIS_IDX),0)+1 FROM USERS_HIS WITH(NOLOCK) WHERE USER_ID = @USER_ID

			   --USERS_HIS 삽입
			   INSERT INTO USERS_HIS 
			   (USER_ID, HIS_IDX, USER_NM, USER_ST, EDT_DT) VALUES
			   (@USER_ID, @HIS_IDX, @USER_NM, @USER_ST, @EDT_DT)
			 END

END
GO

 

해당 쿼리는 업데이트 후 정보를 이력으로 저장 했습니다.

 

 

 

2. 트리거 검증 

 

 1) 검증 쿼리

--변경전
SELECT * FROM USERS

SELECT * FROM USERS_HIS

--USER_ST 및 다른 값 업데이트
UPDATE USERS
  SET USER_ST = 2, USER_NM = '이지은', EDT_DT = GETDATE()
WHERE USER_ID = 'davi'

-- USER_ST 업데이트 후
SELECT * FROM USERS

SELECT * FROM USERS_HIS

 

 2) 결과

 

 

간단하게 작성하려고 했는데 은근히 시간이 오래 걸리네요.

 

참고 하시고 오류 있으면 댓글 부탁드립니다.

반응형
반응형

 

MS SQL에서 해당 테이블이 존재하면 실행되는 조건문입니다.

 

 

예제)

IF EXISTS 사용 시 가장 많이 사용되는 방법인,

조건에 따라 INSERT 와 UPDATE 를 실행하는 예제입니다. 

 

USER_INFO 테이블에 USER_ID 가 '홍길동'이라는 사용자가 있는지 확인하고

'홍길동'이 없다면 INSERT 문을 실행하고

'홍길동'이 있다면 UPDATE 문을 실행하도록 하겠습니다.

 

IF EXISTS (SELECT USER_ID FROM USER_INFO WHERE USER_ID ='홍길동' ) --조건 설정
	BEGIN
		--조건 결과 값이 있을 때
		UPDATE USER_INFO
	END
ELSE
	BEGIN
		--조건 결과 값이 없을 때
		INSERT INTO USER_INFO    
	END

 

 

하지만 조건 결과가 없을 때 한 개만 사용하고 싶다면

 

IF NOT EXISTS 를 사용할 수 있습니다.

 

--조건 결과 값이 있을 때만 사용

IF EXISTS (SELECT 문)

    BEGIN

        '실행할 쿼리'

    END

 

--조건 결과 값이 없을 때만 사용

IF NOT EXISTS (SELECT 문)

    BEGIN

       '실행할 쿼리'

    END

--조건 결과 값이 있을 때만 사용
IF EXISTS (SELECT 문)
	BEGIN        
		'실행할 쿼리'    
	END
    
 
--조건 결과 값이 없을 때만 사용
IF NOT EXISTS (SELECT 문)
	BEGIN
		'실행할 쿼리'
	END

 

반응형
반응형

중소기업이나 데이터 양이 많지 않은 기업에서

 

무료 버전인 Express 버전을 사용하기도 합니다.

 

SQL SERVER Express 버전은 기본적으로 스케줄러 기능이 없기 때문에

 

윈도우 스케줄러를 통한 자동 백업을 사용해야 합니다.

 

 

 

1. 백업 쿼리 파일 생성

 

 

1) 전체 백업

 

 

BACKUP DATABASE ['DB명'TO DSIK = '백업 데이터 저장 경로' WITH INIT, STATS = 10

 

쿼리를 실행시켜 정상 동작하는지 확인한 뒤에

 

 

쿼리 파일을 저장합니다.

 

2) 로그 백업

 

 

BACKUP LOG TEST2 TO DISK = '백업 데이터 저장 경로'

 

로그 쿼리도 동일한 방법으로 쿼리 파일로 만들어 저장합니다.

 

 

 

2. 윈도우 작업스케줄러 설정

 

이제 윈도우 작업 스케줄러로 특정 시간마다 백업 쿼리가 실행되도록 설정할 것입니다.

 

 

 

 

새 작업을 만들고 스케줄 이름을 입력합니다.

 

 

트리거에서 시간 및 옵션을 백업 정책에 맞게 설정합니다.

 

저는 임의로 매일 오후 11시에 백업하도록 설정했습니다.

 

다음은 동작 탭에서 

 

프로그램/스크립트 필드에 sqlcmd -s 서버 주소, 포트번호 -E -i 를 입력합니다.

예) sqlcmd -s 192.168.0.3, 1433 -E -i

 

다음 인수 추가 필드에

1번에서 만들어 놓은 쿼리 파일의 경로를 입력합니다.

예) D:\DB_QUERY_TEST2_FULL.back

 

동작 설정 전에 스크립트가 잘 실행되는지 검증할 필요가 있으니,

명령 프롬프트(cmd)를 실행하여 작성한 스크립트를 검증합니다.

 

검증이 완료되면 작업 스케줄러로 돌아가 스케줄러를 저장합니다.

 

검증 시 스크립트가 실패한다면 이 글을 참조하셔서 TCP/IP 접속 에러를 확인하세요.

 

 

MS SQL TCP/IP 접속 에러 해결

SQL Server에 연결을 설정하는 중에 네트워크 관련 또는 인스턴스 관련 오류가 발생했습니다. 서버를 찾을 수 없거나 액세스할 수 없습니다. SQL Server가 원격 연결을 허용하도록 구성되어 있는지 확인하십시오...

seodavi.tistory.com

 

글에 문제가 있다면 댓글로 지적해주세요.

확인하고 수정하겠습니다.

반응형
반응형

SQL Server에 연결을 설정하는 중에 네트워크 관련 또는 인스턴스 관련 오류가 발생했습니다.

서버를 찾을 수 없거나 액세스할 수 없습니다. SQL Server가 원격 연결을 허용하도록 구성되어 있는지 확인하십시오.

 

위의 오류 메세지는 외부 접속이 허용되지 않을때 발생되는 오류 입니다.

 

확인해야할 포인트는 3가지 입니다.

 

 

 

1. TCP/IP 사용

 

 1) SQL Server Configuration Manager(SQL SERVER 구성관리자) 실행

 

 

 SQL Server 구성관리자를 실행합니다.

 

 

 2) TCP/IP 사용하도록 변경

 

 

 SQL Server 네트워크 구성에서 TCP/IP를 사용하도록 변경 합니다.

 

 

2. PORT 설정

 

 외부에서 접속하려면 TCP포트를 설정해야 합니다.

 

 

 기본포트인 1443으로 설정합니다.

 

 

 

 SQL Server 서비스를 다시 시작합니다.

 

3. 외부 연결 허용 설정

 

 1) SSMS 실행

 2) 서버 속성 선택 

 3) 이 서버에 대한 원격 연결 허용 '체크'

 

 

이상입니다.

 

 

반응형

+ Recent posts