Я ищу встроенную функцию / расширенную функцию в T-SQL для обработки строк, аналогичную String.Format
методу в .NET.
91
Если вы используете 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');
НОТЫ:
FORMATMESSAGE
воспринимается как (безвредная) ошибка
msg_number
.string.Format
T-SQL нет функциональности стиля-стиля, это самое близкое из возможных.взгляните на 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)
источник
Я создал пользовательскую функцию для имитации функциональности string.format. Вы можете использовать это.
stringformat-in-sql
ОБНОВЛЕНИЕ:
эта версия позволяет пользователю изменять разделитель.
-- DROP function will loose the security settings. IF object_id('[dbo].[svfn_FormatString]') IS NOT NULL DROP FUNCTION [dbo].[svfn_FormatString] GO CREATE FUNCTION [dbo].[svfn_FormatString] ( @Format NVARCHAR(4000), @Parameters NVARCHAR(4000), @Delimiter CHAR(1) = ',' ) RETURNS NVARCHAR(MAX) AS BEGIN /* Name: [dbo].[svfn_FormatString] Creation Date: 12/18/2020 Purpose: Returns the formatted string (Just like in C-Sharp) Input Parameters: @Format = The string to be Formatted @Parameters = The comma separated list of parameters @Delimiter = The delimitter to be used in the formatting process Format: @Format = N'Hi {0}, Welcome to our site {1}. Thank you {0}' @Parameters = N'Karthik,google.com' @Delimiter = ',' Examples: SELECT dbo.svfn_FormatString(N'Hi {0}, Welcome to our site {1}. Thank you {0}', N'Karthik,google.com', default) SELECT dbo.svfn_FormatString(N'Hi {0}, Welcome to our site {1}. Thank you {0}', N'Karthik;google.com', ';') */ DECLARE @Message NVARCHAR(400) DECLARE @ParamTable TABLE ( Id INT IDENTITY(0,1), Paramter VARCHAR(1000)) SELECT @Message = @Format ;WITH CTE (StartPos, EndPos) AS ( SELECT 1, CHARINDEX(@Delimiter, @Parameters) UNION ALL SELECT EndPos + (LEN(@Delimiter)), CHARINDEX(@Delimiter, @Parameters, EndPos + (LEN(@Delimiter))) FROM CTE WHERE EndPos > 0 ) INSERT INTO @ParamTable ( Paramter ) SELECT [Id] = SUBSTRING(@Parameters, StartPos, CASE WHEN EndPos > 0 THEN EndPos - StartPos ELSE 4000 END ) FROM CTE UPDATE @ParamTable SET @Message = REPLACE(@Message, '{'+ CONVERT(VARCHAR, Id) + '}', Paramter ) RETURN @Message END
источник
Способ есть, но у него есть свои ограничения. Вы можете использовать
FORMATMESSAGE()
функцию. Он позволяет форматировать строку, используя форматирование, аналогичноеprintf()
функции в C.Однако самым большим ограничением является то, что он будет работать только с сообщениями в таблице sys.messages. Вот статья об этом: microsoft_library_ms186788
Жаль, что нет более простого способа сделать это, потому что бывают случаи, когда вы хотите отформатировать строку / varchar в базе данных. Надеюсь, вы только хотите отформатировать строку стандартным способом и можете использовать
sys.messages
таблицу.По совпадению, вы также можете использовать
RAISERROR()
функцию с очень низким уровнем серьезности, в документации по raiseerror даже упоминается об этом, но результаты только распечатываются. Таким образом, вы не сможете ничего сделать с полученным значением (насколько я понимаю).Удачи!
источник
FORMATMESSAGE()
неверно, однако понятно , потому что он не документирован , но он будет принимать любую строку в качестве первого параметра, см этого ответа на @ g2server .Необработанный t-sql ограничен функциями CHARINDEX (), PATINDEX (), REPLACE () и SUBSTRING () для обработки строк. Но с sql server 2005 и более поздними версиями вы можете настроить определяемые пользователем функции, которые выполняются в .Net, а это означает, что настройка UDF string.format () не должна быть слишком сложной.
источник
Еще одна идея.
Хотя это не универсальное решение - оно простое и работает, по крайней мере, у меня :)
Для одного заполнителя {0}:
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
источник
Вот моя версия. Может быть расширен для размещения большего количества параметров и может расширять форматирование в зависимости от типа. В настоящее время форматируются только типы date и datetime.
Пример:
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)
Вывод:
Функции:
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;
источник
вот что я обнаружил в своих экспериментах с использованием встроенного
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
источник
На данный момент этого действительно не существует (хотя вы, конечно, можете написать свое собственное). Для этого есть ошибка открытого подключения: https://connect.microsoft.com/SQLServer/Feedback/Details/3130221 , которая на момент написания этой статьи имеет всего 1 голос.
источник
На самом деле встроенной функции, аналогичной строковой, нет. Функция форматирования .NET доступна в SQL-сервере.
В SQL-сервере есть функция FORMATMESSAGE (), но она имитирует функцию printf () языка C, а не функцию string.Format .NET.
SELECT FORMATMESSAGE('This is the %s and this is the %s.', 'first variable', 'second variable') AS Result
источник
Не совсем так, но я бы посмотрел некоторые статьи по обработке строк (среди прочего), написанные "Phil Factor" (geddit?) На Simple Talk.
источник
это плохой подход. вы должны работать со сборками dll, которые сделают то же самое за вас с большей производительностью.
источник