2010-06-02 4 views
0

CSV 내보내기의 원시 텍스트와 관련 타임 스탬프가 하나의 레코드가 하나의 내보내기와 동일한 데이터베이스에 저장된다고 가정 해보십시오.ntext 열에 저장된 csv 데이터에 대한 쿼리 실행

사람은 에 대한 방법은 데이터베이스에 두 번째 연결을 만들거나 데이터를 파일로 보낸 다음 CSV 텍스트 드라이버를 사용하여 재개하지 않고 해당 필드에 저장된 CSV 파일에 쿼리를 실행해야합니까?

가 있다고 가정 :

1) 솔루션

2)의 서버에 실제 파일을 쓸 수 없습니다 당신이 할 수없는/OPENROWSET (서버 w 서버에 두 번째 연결, 그것은 100 %의 SQL 솔루션을해야한다는 사용자 이름 & 암호 변경)

3) - 수 있어야합니다 당신은 한 번에 하나의 기록 작업에 필요한 SP에

4)로 실행하는 - 솔루션을 sele을 설명 할 필요가 없다. DB에 저장된 여러 csv 파일에서 cting.

+0

정확하게 "쿼리 실행"을 구성하는 것은 무엇입니까? –

+0

CSV 데이터의 행 - 행 구조가 동일합니까? 그 구조가 미리 정의되어 있습니까? –

+0

@PK CSV 데이터의 행 - 행 구조는 동일하며 사전 정의됩니다. @Tom H. 간단한 SELECT 만 처리해야한다고 가정합니다 (하위 쿼리가없고 CSV 데이터의 레코드가 변경되지 않습니다). – seraphym

답변

0

내 용액 테이블 변수에 CSV 데이터를 파싱하는 UDF를 작성하는 것이다. 그런 다음 SP에서 CSV를 검색하고이를 UDF로 전달한 다음 테이블 변수에 대해 쿼리를 실행합니다.

에서, CSV 값에서 테이블을 반환하는 UDF를 작성

먼저 (새 라인을 결정하기 위해 (13) CHAR를 사용하여 데이터 작업을 변경해야 할 수도 있습니다) :

CREATE FUNCTION [dbo].[fnParseCSV] (@InputString NVARCHAR(MAX), @Delimiter NCHAR(1) = ',') 
RETURNS @tbl TABLE (ID int, Val NVARCHAR(64)) AS 
BEGIN 
    declare @singleLine nvarchar(max) 
    declare @id int 
    declare @val varchar(64) 

    WHILE LEN(@InputString) > 0 BEGIN 
     IF CHARINDEX(char(13), @InputString) > 0 BEGIN 
      SELECT @singleLine = SUBSTRING(@InputString, 1, CHARINDEX(char(13), @InputString) - 1) 
      IF CHARINDEX(@Delimiter, @singleline) > 0 BEGIN 
       SELECT @id = convert(int, SUBSTRING(@singleline, 1, CHARINDEX(@Delimiter, @singleline) - 1)) 
       SELECT @val = RIGHT(@singleline, LEN(@singleline) - CHARINDEX(@Delimiter, @singleline)) 
       INSERT INTO @tbl (id, val) values (@id, @val) 
      END 

      SELECT @InputString = RIGHT(@InputString, LEN(@InputString) - CHARINDEX(char(13), @InputString)) 
     END 
     ELSE 
     BEGIN 
      IF CHARINDEX(@Delimiter, @inputString) > 0 
      BEGIN 
       SELECT @id = convert(int, SUBSTRING(@inputString, 1, CHARINDEX(@Delimiter, @inputString) - 1)) 
       SELECT @val = RIGHT(@inputString, LEN(@inputString) - CHARINDEX(@Delimiter, @inputString)) 
       INSERT INTO @tbl (id, val) values (@id, @val) 
      END 
      set @inputString = '' 
     END 
    END 
    RETURN 
END 

그런 다음 실행 해당 출력에 대한 쿼리 :

select * from dbo.fnParseCsv('123,val1' + char(13) + '456,val2' + CHAR(13) + '789,val3', ',') 
0

열을 구문 분석 할 수있는 일련의 사용자 정의 함수를 설정할 수 있습니다. 그것은 천천히 진행될 것이고 튼튼하지 않을 것입니다.

비록 예로서

(등 진짜 오류 검사와, 오직 최소 테스트)

IF OBJECT_ID('dbo.Test_CSV_Search') IS NOT NULL 
    DROP TABLE dbo.Test_CSV_Search 
GO 
CREATE TABLE dbo.Test_CSV_Search 
(
    my_id INT IDENTITY NOT NULL, 
    txt  VARCHAR(MAX) NOT NULL, 
    CONSTRAINT PK_Test_CSV_Search PRIMARY KEY CLUSTERED (my_id) 
) 
GO 
INSERT INTO dbo.Test_CSV_Search (txt) VALUES ('11, 12, 13, 14,15,16 
21,22, 23,24, 25,26 
31,22,33,34,35,36') 
GO 
IF OBJECT_ID('dbo.Get_CSV_Row') IS NOT NULL 
    DROP FUNCTION dbo.Get_CSV_Row 
GO 
CREATE FUNCTION dbo.Get_CSV_Row 
(@my_id INT, @col_num SMALLINT, @search_value VARCHAR(100)) 
RETURNS @results TABLE (row_num INT, row_txt VARCHAR(MAX)) 
AS 
BEGIN 
    DECLARE 
     @csv_txt VARCHAR(MAX), 
     @full_row VARCHAR(MAX), 
     @start_pos INT, 
     @end_pos INT, 
     @col_txt VARCHAR(100), 
     @cur_col SMALLINT, 
     @line_start INT, 
     @line_end INT, 
     @row_num INT 

    SELECT @csv_txt = txt + CHAR(10) FROM dbo.Test_CSV_Search WHERE my_id = @my_id 

    SELECT 
     @line_start = 1, 
     @cur_col = 1, 
     @start_pos = 1, 
     @row_num = 1 

    WHILE (CHARINDEX(CHAR(10), @csv_txt, @line_start) > 0) 
    BEGIN 
     SELECT 
      @line_end = CHARINDEX(CHAR(10), @csv_txt, @line_start), 
      @end_pos = CHARINDEX(',', @csv_txt, @start_pos) 

     WHILE (@cur_col < @col_num) 
     BEGIN 
      SET @start_pos = @end_pos + 1 
      SET @end_pos = CHARINDEX(',', @csv_txt, @start_pos) 
      SET @cur_col = @cur_col + 1 
     END 

     IF (RTRIM(LTRIM(SUBSTRING(@csv_txt, @start_pos, @end_pos - @start_pos))) = @search_value) 
     BEGIN 
      INSERT INTO @results (row_num, row_txt) VALUES (@row_num, RTRIM(LTRIM(SUBSTRING(@csv_txt, @line_start, @line_end - @line_start)))) 
     END 

     SELECT 
      @line_start = @line_end + 1, 
      @start_pos = @line_end + 1, 
      @cur_col = 1, 
      @row_num = @row_num + 1 
    END 

    RETURN 
END 
GO 

SELECT * FROM dbo.Get_CSV_Row(1, 1, '11') 
관련 문제