/* 일반적인 방법 */
ALTER FUNCTION [dbo].[FN_Split] (
    @str        NVARCHAR(MAX)     -- 원본 문자열
  , @Delimeter  CHAR(1)   = '|'  -- 구분기호(Default '|')
)
RETURNS @SplitedResult TABLE (
    Idx INT IDENTITY(1,1) PRIMARY KEY -- 결과 배열 인덱스
  , Val NVARCHAR(MAX)                 -- 인덱스에 해달하는 결과 문자열
) AS
BEGIN
    -- Declare index
    DECLARE @Idx            INT
    -- Sets the index initialize
    SET @Idx = -1;

    SET @str = ISNULL(@str, '')
    SET @Delimeter = ISNULL(@Delimeter, '|')

    WHILE (LEN(@str) > 0)
    BEGIN
        SET @Idx = CHARINDEX(@Delimeter , @str) ;

        IF (@Idx = 0) AND (LEN(@str) > 0)
        BEGIN
            INSERT INTO @SplitedResult VALUES (RTRIM(LTRIM(@str))) ;
            BREAK ;
        END

        IF (@Idx > 1)
        BEGIN
            INSERT INTO @SplitedResult VALUES (RTRIM(LTRIM(LEFT(@str, @Idx - 1)))) ;
            SET @str = RIGHT(@str, (LEN(@str) - @Idx)) ;
        END
        ELSE
            SET @str = RIGHT(@str, (LEN(@str) - @Idx)) ;
    END

    RETURN
END


/* XML을 이용한 방법 */
IF OBJECT_ID('dbo.Split') IS NOT NULL
    DROP FUNCTION dbo.Split GO
CREATE FUNCTION dbo.Split(@data VARCHAR(MAX), @delimiter VARCHAR(1))
RETURNS TABLE
AS
BEGIN
    DECLARE @textXML XML;
    SELECT    @textXML = CAST('<d>' + REPLACE(@data, @delimiter, '</d><d>') + '</d>' AS XML);

    RETURN (SELECT  T.split.value('.', 'nvarchar(max)') AS data
            FROM    @textXML.nodes('/d') T(split))
END

Some test results:
--------------------------------
Number of Items: 100,000
SplitString Time: 46 ms
Xml2IntList Time: 983 ms
--------------------------------
Number of Items: 10,000
SplitString Time: 40 ms
Xml2IntList Time: 93 ms
--------------------------------
Number of Items: 1,000
SplitString Time: 38 ms
Xml2IntList Time: 15 ms
--------------------------------
Number of Items: 100
SplitString Time: 25 ms
Xml2IntList Time: 1.5 ms
--------------------------------

AND



SELECT
       memoIdx,
       STUFF((
             SELECT ',' + cast(memIdx as varchar(3))
             FROM    MemoReceive b
             WHERE   b.memoIdx = a.memoIdx
             FOR XML PATH('')
        ),1,1,'') AS NAME
FROM MemoReceive a 


FOR XML PATH('') 가 핵심
STUFF는 합쳐진 문자열 맨 앞의 ',' 를 제거하는 역활

'SQL > MS-SQL' 카테고리의 다른 글

[SQL] Split 구현하기  (8) 2010.01.27
[SQL] 다중 조건 처리하기  (4) 2009.12.28
MS-SQL 2005에서 페이징 처리  (2) 2008.04.28

AND


DECLARE 
 @value1 varchar(10),
 @value2 varchar(20)

SET @value1 = ''
SET @value2 = 'value'

SELECT * FROM [TABLE] WITH(NOLOCK)
WHERE
     ([COL1] = '' OR [COL1] = @value1)
     AND ([COL2] = '' OR [COL2] = @value2)

위와 같이 사용하면 조건값이 '' 이면 참이 되어 OR 뒤의 조건이 실행되지 않는다.
때문에 [COL1] = @value1의 조건은 무시되고 [COL2] = @value2 조건만 검색하게 된다.

AND


현재 위치의 정보를 보여주고 다음 목적지의 이름을 가져와야 하는데 뭔가 간단한 방법이 있지 않을까 해서 알아보니 오라클에 LEAD() 라는 함수가 존재하더군요.

LEAD() 함수 덕분에 간단하게 다음 로우에 있는 데이터를 가져 올 수 있게 되었네요.

반대로 이전 로우의 데이터를 가져 올 때는 LAG() 라는 함수를 같은 방식으로 사용하면 됩니다.

아래는 오라클 사이트에서의 LEAD() 함수에 대한 설명 원문입니다.


Syntax

Description of lead.gif follows
Description of the illustration lead.gif

See Also:

"Analytic Functions" for information on syntax, semantics, and restrictions, including valid forms of value_expr

Purpose

LEAD is an analytic function. It provides access to more than one row of a table at the same time without a self join. Given a series of rows returned from a query and a position of the cursor, LEAD provides access to a row at a given physical offset beyond that position.

If you do not specify offset, then its default is 1. The optional default value is returned if the offset goes beyond the scope of the table. If you do not specify default, then its default value is null.

You cannot nest analytic functions by using LEAD or any other analytic function for value_expr. However, you can use other built-in function expressions for value_expr.

See Also:

"About SQL Expressions" for information on valid forms of expr and LAG

Examples

The following example provides, for each employee in the employees table, the hire date of the employee hired just after:

SELECT last_name, hire_date, 
LEAD(hire_date, 1) OVER (ORDER BY hire_date) AS "NextHired"
FROM employees WHERE department_id = 30
ORDER BY last_name, hire_date, "NextHired";

LAST_NAME HIRE_DATE NextHired
------------------------- --------- ---------
Baida 24-DEC-97 15-NOV-98
Colmenares 10-AUG-99
Himuro 15-NOV-98 10-AUG-99
Khoo 18-MAY-95 24-JUL-97
Raphaely 07-DEC-94 18-MAY-95
Tobias 24-JUL-97 24-DEC-97


출처 : http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/functions079.htm#i83834

'SQL > ORACLE' 카테고리의 다른 글

오라클에서 IF NOT EXISTS 구현  (3) 2009.05.07

AND


 IF NOT EXITS (SELECT * FROM [TABLE])
   INSERT ...

MS-SQL 에서는 위와 같이 테이블의 값을 조회해서 없으면 인서트 하는 쿼리를 아래와 같이 IF NOT EXISTS를 이용해서 쉽게 구현할 수 있었는데

오라클에서는 IF NOT EXISTS() 가 안되는것 같더군요..

해서 검색해본 결과

 INSERT INTO [TABLE]
    SELECT [COL] FROM DUAL
WHERE NOT EXISTS (SELECT * FROM [TABLE] WHERE {});

이와 같은 식으로 인서트 할 때 WHERE 조건에 NOT EXISTS를 사용해서 처리가 가능합니다.
이처럼 인서트 외에도 각 로직에 맞게끔 WHERE NOT EXISTS 를 잘 활용하면 SQL과 같은 기능을 구현하는데 무리가 없을 듯 합니다.

저 개인적으로는 MS-SQL에 있는 IF NOT EXISTS가 더 맘에 들지만요;;;

'SQL > ORACLE' 카테고리의 다른 글

다음 행의 데이터를 가져오는 LEAD 함수  (3) 2009.05.12

AND


SQL 2005에서는 페이징 방법을 새롭게 적용 있습니다.

또한 쿼리 구문을 복잡하게 사용 하시던 분들은 SQL 2005에서 개발 한다면

아래와 같이 쉽게 사용 하시기 바랍니다.

 

 

DECLARE @CURRPAGE  INT

DECLARE @MAXPAGE   INT

 

SET @CURRPAGE = [ 페이지 주소]

SET @MAXPAGE  = [페이지당 출력 ]

 

 

-- 1. WITH 구문을이용해서하는방법

WITH TEMP_TABLE AS

(

        -- ====================================================================

        SELECT

                       ROW_NUMBER() OVER(ORDER BY [소트할 내용]) AS RowNum,

                       *

               FROM

                       [테이블 ]

        -- ====================================================================

)

SELECT * FROM TEMP_TABLE WHERE ROWNUM BETWEEN ( ( @CURRPAGE - 1 ) * ( @MAXPAGE + 1 ) ) AND ( @CURRPAGE * @MAXPAGE )

 

-- 2. FROM를이용해서하는방법

SELECT

        *

        FROM

               (

                       -- ====================================================================

                       SELECT

                                      ROW_NUMBER() OVER(ORDER BY [소트할 내용]) as RowNum,

                                      *

                              FROM

                                      [테이블 ]

                       -- ====================================================================

               ) AS A

WHERE ROWNUM BETWEEN ( ( @CURRPAGE - 1 ) * @MAXPAGE ) + AND ( @CURRPAGE * @MAXPAGE )

출처 : http://msmvp.egloos.com/3453597

'SQL > MS-SQL' 카테고리의 다른 글

[SQL] Split 구현하기  (8) 2010.01.27
[SQL] 여러 로우를 하나의 로우(필드, 컬럼)으로 합치기  (0) 2010.01.25
[SQL] 다중 조건 처리하기  (4) 2009.12.28

AND