String.Format
.NET 의 메서드 와 유사한 문자열 조작을 위해 T-SQL의 기본 제공 함수 / 확장 함수를 찾고 있습니다.
답변
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
은 (무해한) 오류로 나타납니다.
답변
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)
답변
답변
방법이 있지만 한계가 있습니다. FORMATMESSAGE()
기능을 사용할 수 있습니다 . printf()
C 의 함수 와 유사한 형식을 사용하여 문자열을 형식화 할 수 있습니다 .
그러나 가장 큰 제한은 sys.messages 테이블의 메시지에서만 작동한다는 것입니다. 여기에 대한 기사가 있습니다. microsoft_library_ms186788
데이터베이스에서 문자열 / varchar 형식을 지정하려는 경우가 있기 때문에이 작업을 수행하는 더 쉬운 방법이 없다는 것은 일종의 부끄러운 일입니다. 바라건대 당신은 표준 방식으로 문자열을 포맷하고 sys.messages
테이블을 사용할 수 있습니다 .
우연히도 RAISERROR()
심각도가 매우 낮은 함수를 사용할 수도 있습니다. raiseerror에 대한 문서에서는이 작업을 언급하기도하지만 결과 만 인쇄됩니다. 따라서 결과 값으로 (내가 이해 한) 아무것도 할 수 없습니다.
행운을 빕니다!
답변
원시 t-sql은 문자열 조작을 위해 CHARINDEX (), PATINDEX (), REPLACE () 및 SUBSTRING ()으로 제한됩니다. 그러나 SQL Server 2005 이상에서는 .Net에서 실행되는 사용자 정의 함수를 설정할 수 있습니다. 즉, string.format () UDF 설정이 너무 어렵지 않아야합니다.
답변
한 가지 더.
이것은 보편적 인 해결책은 아니지만-적어도 나에게는 간단하고 작동합니다. 🙂
자리 표시 자 {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);
답변
끝 위치를 계산하는 동안 약간의 수정이 있다고 생각합니다.
여기에 올바른 기능이 있습니다.
**>>**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