T-SQL의 기능과 같은 String.Format?


90

String.Format.NET 의 메서드 와 유사한 문자열 조작을 위해 T-SQL의 기본 제공 함수 / 확장 함수를 찾고 있습니다.

답변:


70

SQL Server 2012 이상을 사용하는 경우 FORMATMESSAGE. 예.

DECLARE @s NVARCHAR(50) = 'World';
DECLARE @d INT = 123;
SELECT FORMATMESSAGE('Hello %s, %d', @s, @d)
-- RETURNS 'Hello World, 123'

MSDN의 추가 예 : FORMATMESSAGE

SELECT FORMATMESSAGE('Signed int %i, %d %i, %d, %+i, %+d, %+i, %+d', 5, -5, 50, -50, -11, -11, 11, 11);
SELECT FORMATMESSAGE('Signed int with leading zero %020i', 5);
SELECT FORMATMESSAGE('Signed int with leading zero 0 %020i', -55);
SELECT FORMATMESSAGE('Unsigned int %u, %u', 50, -50);
SELECT FORMATMESSAGE('Unsigned octal %o, %o', 50, -50);
SELECT FORMATMESSAGE('Unsigned hexadecimal %x, %X, %X, %X, %x', 11, 11, -11, 50, -50);
SELECT FORMATMESSAGE('Unsigned octal with prefix: %#o, %#o', 50, -50);
SELECT FORMATMESSAGE('Unsigned hexadecimal with prefix: %#x, %#X, %#X, %X, %x', 11, 11, -11, 50, -50);
SELECT FORMATMESSAGE('Hello %s!', 'TEST');
SELECT FORMATMESSAGE('Hello %20s!', 'TEST');
SELECT FORMATMESSAGE('Hello %-20s!', 'TEST');
SELECT FORMATMESSAGE('Hello %20s!', 'TEST');

메모:

  • 2012 년에 문서화되지 않음
  • 2044 자로 제한
  • % 기호를 이스케이프하려면 두 배로해야합니다.
  • 확장 이벤트에 오류를 기록하는 경우 호출 FORMATMESSAGE은 (무해한) 오류로 나타납니다.

1
당신은 SQL 2012을 사용하는 경우 사용할 수있는 포맷 기능을 모든없이 위의 합병증 :
반전 엔지니어

1
이것은 훨씬 더 많은 표를 가져야합니다! 내장에서만 작동한다고 가정했기 때문에 멋진 찾기는 항상 피했습니다 msg_number.
Lankymart

1
@Lankymart, 범프! 나는 이것이 받아 들여진 대답이어야한다는 데 동의한다 : 간단하고, 내장되어 있고 훌륭하게 작동했다.
Robert Synoradzki

5
@bijayk 특정 자리 표시 자 이름 만 허용합니다 (예 : 문자열의 경우 % s, 정수의 경우 % i).
g2server

2
@lostmylogin string.FormatT-SQL 에는 스타일 기능 이 없습니다 . 이것이 가장 가까운 기능입니다.
Ian Kemp

53

xp_sprintf 살펴 보십시오 . 아래 예.

DECLARE @ret_string varchar (255)
EXEC xp_sprintf @ret_string OUTPUT, 
    'INSERT INTO %s VALUES (%s, %s)', 'table1', '1', '2'
PRINT @ret_string

결과는 다음과 같습니다.

INSERT INTO table1 VALUES (1, 2)

이 문자열의 최대 크기 (255 자 제한)에 대한 문제를 발견 했으므로 사용할 수 있는 대체 기능 이 있습니다.

create function dbo.fnSprintf (@s varchar(MAX), 
                @params varchar(MAX), @separator char(1) = ',')
returns varchar(MAX)
as
begin
declare @p varchar(MAX)
declare @paramlen int

set @params = @params + @separator
set @paramlen = len(@params)
while not @params = ''
begin
    set @p = left(@params+@separator, charindex(@separator, @params)-1)
    set @s = STUFF(@s, charindex('%s', @s), 2, @p)
    set @params = substring(@params, len(@p)+2, @paramlen)
end
return @s
end

위와 같은 결과를 얻으려면 다음과 같이 함수를 호출합니다.

print dbo.fnSprintf('INSERT INTO %s VALUES (%s, %s)', 'table1,1,2', default)

7
매개 변수에 쉼표가 포함 된 경우 FYI 만 있으면 운이 좋지 않습니다. 우연히 하나를 통과하면 무엇이 잘못되었는지 파악하는 데 어려움을 겪을 것입니다.
Kyle

15

string.format 기능을 모방하기 위해 사용자 정의 함수를 만들었습니다. 사용할 수 있습니다.

stringformat-in-sql


프로덕션에서 xp_ 함수 / SP 사용에 대한 예약이 있으므로이 솔루션을 좋아합니다. 나는 당신의 코드를 기반으로 사용하고 구분 기호의 전달을 허용하여 데이터에서 사용되는 쉼표에 대한 우려를 제거했습니다.
Tim Friesen

4

방법이 있지만 한계가 있습니다. FORMATMESSAGE()기능을 사용할 수 있습니다 . printf()C 의 함수 와 유사한 형식을 사용하여 문자열을 형식화 할 수 있습니다 .

그러나 가장 큰 제한은 sys.messages 테이블의 메시지에서만 작동한다는 것입니다. 여기에 대한 기사가 있습니다. microsoft_library_ms186788

데이터베이스에서 문자열 / varchar 형식을 지정하려는 경우가 있기 때문에이 작업을 수행하는 더 쉬운 방법이 없다는 것은 일종의 부끄러운 일입니다. 바라건대 당신은 표준 방식으로 문자열을 포맷하고 sys.messages테이블을 사용할 수 있습니다 .

우연히도 RAISERROR()심각도가 매우 낮은 함수를 사용할 수도 있습니다. raiseerror에 대한 문서에서는이 작업을 언급하기도하지만 결과 만 인쇄됩니다. 따라서 결과 값으로 (내가 이해 한) 아무것도 할 수 없습니다.

행운을 빕니다!


1
이것은 오래된 답변이지만 가정 FORMATMESSAGE()은 정확하지 않지만 문서화되지 않았기 때문에 이해할 수 있지만 첫 번째 매개 변수로 모든 문자열을 허용합니다 . @ g2server의 답변 을 참조하십시오 .
Lankymart

@Lankymart 당신이 맞습니다-이것은 오래된 대답입니다. 문자열을 받아들이는 기능은 SQL 2012까지 추가되지 않았습니다.
jj.

3

원시 t-sql은 문자열 조작을 위해 CHARINDEX (), PATINDEX (), REPLACE () 및 SUBSTRING ()으로 제한됩니다. 그러나 SQL Server 2005 이상에서는 .Net에서 실행되는 사용자 정의 함수를 설정할 수 있습니다. 즉, string.format () UDF 설정이 너무 어렵지 않아야합니다.


2

한 가지 더.

이것은 보편적 인 해결책은 아니지만-적어도 나에게는 간단하고 작동합니다. :)

자리 표시 자 {0} 1 개의 경우 :

create function dbo.Format1
(
    @String  nvarchar(4000),
    @Param0  sql_variant
)
returns nvarchar(4000)
as
begin
    declare @Null nvarchar(4) = N'NULL';

    return replace(@String, N'{0}', cast(isnull(@Param0, @Null) as nvarchar(4000)));    
end

두 자리 표시 자 {0} 및 {1}의 경우 :

create function dbo.Format2
(
    @String  nvarchar(4000),
    @Param0  sql_variant,
    @Param1  sql_variant
)
returns nvarchar(4000)
as
begin
    declare @Null nvarchar(4) = N'NULL';

    set @String = replace(@String, N'{0}', cast(isnull(@Param0, @Null) as nvarchar(4000)));
       return     replace(@String, N'{1}', cast(isnull(@Param1, @Null) as nvarchar(4000))); 
end

세 개의 자리 표시 자 {0}, {1} 및 {2}의 경우 :

create function dbo.Format3
(
    @String  nvarchar(4000),
    @Param0  sql_variant,
    @Param1  sql_variant,
    @Param2  sql_variant
)
returns nvarchar(4000)
as
begin
    declare @Null nvarchar(4) = N'NULL';

    set @String = replace(@String, N'{0}', cast(isnull(@Param0, @Null) as nvarchar(4000)));
    set @String = replace(@String, N'{1}', cast(isnull(@Param1, @Null) as nvarchar(4000))); 
       return     replace(@String, N'{2}', cast(isnull(@Param2, @Null) as nvarchar(4000)));
end

등등...

이러한 접근 방식을 통해 SELECT 문과 nvarchar, number, bit 및 datetime 데이터 유형의 매개 변수와 함께 이러한 함수를 사용할 수 있습니다.

예를 들면 :

declare @Param0 nvarchar(10) = N'IPSUM' ,
        @Param1 int          = 1234567  ,
        @Param2 datetime2(0) = getdate();

select dbo.Format3(N'Lorem {0} dolor, {1} elit at {2}', @Param0, @Param1, @Param2);  

1

끝 위치를 계산하는 동안 약간의 수정이 있다고 생각합니다.

여기에 올바른 기능이 있습니다.

**>>**IF OBJECT_ID( N'[dbo].[FormatString]', 'FN' ) IS NOT NULL
DROP FUNCTION [dbo].[FormatString]
GO
/***************************************************
Object Name : FormatString
Purpose : Returns the formatted string.
Original Author : Karthik D V http://stringformat-in-sql.blogspot.com/
Sample Call:
SELECT dbo.FormatString ( N'Format {0} {1} {2} {0}', N'1,2,3' )
*******************************************/
CREATE FUNCTION [dbo].[FormatString](
    @Format NVARCHAR(4000) ,
    @Parameters NVARCHAR(4000)
)
RETURNS NVARCHAR(4000)
AS
BEGIN
    --DECLARE @Format NVARCHAR(4000), @Parameters NVARCHAR(4000) select @format='{0}{1}', @Parameters='hello,world'
    DECLARE @Message NVARCHAR(400), @Delimiter CHAR(1)
    DECLARE @ParamTable TABLE ( ID INT IDENTITY(0,1), Parameter VARCHAR(1000) )
    Declare @startPos int, @endPos int
    SELECT @Message = @Format, @Delimiter = ','**>>**

    --handle first parameter
     set @endPos=CHARINDEX(@Delimiter,@Parameters)
    if (@endPos=0 and @Parameters is not null) --there is only one parameter
        insert into @ParamTable (Parameter) values(@Parameters)
    else begin
        insert into @ParamTable (Parameter) select substring(@Parameters,0,@endPos)
    end

    while @endPos>0
    Begin
        --insert a row for each parameter in the 
        set @startPos = @endPos + LEN(@Delimiter)
        set @endPos = CHARINDEX(@Delimiter,@Parameters, @startPos)
        if (@endPos>0)
            insert into @ParamTable (Parameter) 
                select substring(@Parameters,@startPos,@endPos - @startPos)
            else
                insert into @ParamTable (Parameter) 
                select substring(@Parameters,@startPos,4000)            
    End

    UPDATE @ParamTable SET @Message = 
        REPLACE ( @Message, '{'+CONVERT(VARCHAR,ID) + '}', Parameter )
    RETURN @Message
END
Go
grant execute,references on dbo.formatString to public 

1

여기 내 버전입니다. 더 많은 수의 매개 변수를 수용하도록 확장 할 수 있으며 유형에 따라 형식을 확장 할 수 있습니다. 현재 날짜 및 날짜 시간 유형 만 형식화됩니다.

예:

select dbo.FormatString('some string %s some int %s date %s','"abcd"',100,cast(getdate() as date),DEFAULT,DEFAULT)
select dbo.FormatString('some string %s some int %s date time %s','"abcd"',100,getdate(),DEFAULT,DEFAULT)

산출:

some string "abcd" some int 100 date 29-Apr-2017
some string "abcd" some int 100 date time 29-Apr-2017 19:40

기능 :

create function dbo.FormatValue(@param sql_variant)
returns nvarchar(100)
begin
/*
Tejasvi Hegde, 29-April-2017
Can extend formatting here.
*/
    declare @result nvarchar(100)

    if (SQL_VARIANT_PROPERTY(@param,'BaseType') in ('date'))
    begin
       select @result = REPLACE(CONVERT(CHAR(11), @param, 106), ' ', '-')
    end
    else  if (SQL_VARIANT_PROPERTY(@param,'BaseType') in ('datetime','datetime2'))
    begin
       select @result = REPLACE(CONVERT(CHAR(11), @param, 106), ' ', '-')+' '+CONVERT(VARCHAR(5),@param,108)
    end
    else
    begin
       select @result = cast(@param as nvarchar(100))
    end
    return @result

/*
BaseType:
bigint
binary
char
date
datetime
datetime2
datetimeoffset
decimal
float
int
money
nchar
numeric
nvarchar
real
smalldatetime
smallint
smallmoney
time
tinyint
uniqueidentifier
varbinary
varchar
*/   

end;


create function dbo.FormatString(
    @format nvarchar(4000)
    ,@param1 sql_variant = null
    ,@param2 sql_variant = null
    ,@param3 sql_variant = null
    ,@param4 sql_variant = null
    ,@param5 sql_variant = null
    )
returns nvarchar(4000)
begin
/*
Tejasvi Hegde, 29-April-2017

select dbo.FormatString('some string value %s some int %s date %s','"abcd"',100,cast(getdate() as date),DEFAULT,DEFAULT)
select dbo.FormatString('some string value %s some int %s date time %s','"abcd"',100,getdate(),DEFAULT,DEFAULT)
*/

    declare @result nvarchar(4000)

    select @param1 = dbo.formatValue(@param1)
    ,@param2 = dbo.formatValue(@param2)
    ,@param3 = dbo.formatValue(@param3)
    ,@param4 = dbo.formatValue(@param4)
    ,@param5 = dbo.formatValue(@param5)

    select @param2 = cast(@param2 as nvarchar)
    EXEC xp_sprintf @result OUTPUT,@format , @param1, @param2, @param3, @param4, @param5

    return @result

end;

SQL Server 2008+에 대한 가장 간단한 대답입니다. 입력을 별도의 매개 변수로 유지합니다. xp_sprintf 기능을 사용하며 쉽게 확장 할 수 있습니다. xp_sprintf - docs.microsoft.com/en-us/sql/relational-databases/...
제프 루이스

0

여기에 내장 된

FORMATMESSAGE () 함수

sp_addmessage @msgnum=50001,@severity=1,@msgText='Hello %s you are #%d',@replace='replace'
SELECT FORMATMESSAGE(50001, 'Table1', 5)

sp_addmessage를 호출하면 메시지 템플릿이 시스템 테이블 master.dbo.sysmessages (SQLServer 2000에서 확인 됨)에 저장됩니다.

테이블에서 템플릿 문자열의 추가 및 제거를 직접 관리해야합니다. 정말 원하는 것이 결과 화면에 빠른 메시지를 출력하는 것이라면 어색합니다.

Kathik DV에서 제공하는 솔루션은 흥미로워 보이지만 SQL Server 2000에서는 작동하지 않습니다. 그래서 약간 변경했으며이 버전은 모든 SQL Server 버전에서 작동합니다.

IF OBJECT_ID( N'[dbo].[FormatString]', 'FN' ) IS NOT NULL
    DROP FUNCTION [dbo].[FormatString]
GO
/***************************************************
Object Name : FormatString
Purpose : Returns the formatted string.
Original Author : Karthik D V http://stringformat-in-sql.blogspot.com/
Sample Call:
SELECT dbo.FormatString ( N'Format {0} {1} {2} {0}', N'1,2,3' )
*******************************************/
CREATE FUNCTION [dbo].[FormatString](
@Format NVARCHAR(4000) ,
@Parameters NVARCHAR(4000)
)
RETURNS NVARCHAR(4000)
AS
BEGIN
    --DECLARE @Format NVARCHAR(4000), @Parameters NVARCHAR(4000) select @format='{0}{1}', @Parameters='hello,world'
    DECLARE @Message NVARCHAR(400), @Delimiter CHAR(1)
    DECLARE @ParamTable TABLE ( ID INT IDENTITY(0,1), Parameter VARCHAR(1000) )
    Declare @startPos int, @endPos int
    SELECT @Message = @Format, @Delimiter = ','

    --handle first parameter
     set @endPos=CHARINDEX(@Delimiter,@Parameters)
    if (@endPos=0 and @Parameters is not null) --there is only one parameter
        insert into @ParamTable (Parameter) values(@Parameters)
    else begin
        insert into @ParamTable (Parameter) select substring(@Parameters,0,@endPos)
    end

    while @endPos>0
    Begin
        --insert a row for each parameter in the 
        set @startPos = @endPos + LEN(@Delimiter)
        set @endPos = CHARINDEX(@Delimiter,@Parameters, @startPos)
        if (@endPos>0)
            insert into @ParamTable (Parameter) select substring(@Parameters,@startPos,@endPos)
        else
            insert into @ParamTable (Parameter) select substring(@Parameters,@startPos,4000)            
    End

    UPDATE @ParamTable SET @Message = REPLACE ( @Message, '{'+CONVERT(VARCHAR,ID) + '}', Parameter )
    RETURN @Message
END
Go
    grant execute,references on dbo.formatString to public

용법:

print dbo.formatString('hello {0}... you are {1}','world,good')
--result: hello world... you are good


-1

실제로 string과 유사한 내장 기능은 없으며 .NET의 Format 기능은 SQL Server에서 사용할 수 있습니다.

SQL 서버에는 FORMATMESSAGE () 함수가 있지만 .NET의 string.Format 함수가 아닌 C의 printf () 함수와 유사합니다.

SELECT FORMATMESSAGE('This is the %s and this is the %s.', 'first variable', 'second variable') AS Result

-2

정확히는 아니지만 Simple Talk에서 "Phil Factor"(geddit?)가 작성한 문자열 처리 에 대한 기사 를 살펴 보겠습니다.


-3

이것은 나쁜 접근입니다. 더 나은 성능으로 동일한 작업을 수행하는 어셈블리 dll로 작업해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.