Estoy buscando una función incorporada / función extendida en T-SQL para la manipulación de cadenas similar al String.Format
método en .NET.
90
Si está utilizando SQL Server 2012 y superior, puede utilizar FORMATMESSAGE
. p.ej.
DECLARE @s NVARCHAR(50) = 'World';
DECLARE @d INT = 123;
SELECT FORMATMESSAGE('Hello %s, %d', @s, @d)
-- RETURNS 'Hello World, 123'
Más ejemplos de 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');
NOTAS:
FORMATMESSAGE
aparece como un error (inofensivo)
msg_number
.string.Format
funcionalidad de estilo en T-SQL, esto es lo más cercano que obtendrá.eche un vistazo a xp_sprintf . ejemplo a continuación.
DECLARE @ret_string varchar (255) EXEC xp_sprintf @ret_string OUTPUT, 'INSERT INTO %s VALUES (%s, %s)', 'table1', '1', '2' PRINT @ret_string
El resultado se ve así:
INSERT INTO table1 VALUES (1, 2)
Acabo de encontrar un problema con el tamaño máximo (límite de 255 caracteres) de la cadena con esto, por lo que hay una función alternativa que puede usar:
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
Para obtener el mismo resultado que el anterior, llame a la función de la siguiente manera:
print dbo.fnSprintf('INSERT INTO %s VALUES (%s, %s)', 'table1,1,2', default)
fuente
He creado una función definida por el usuario para imitar la funcionalidad string.format. Puedes usarlo.
stringformat-in-sql
fuente
Hay una forma, pero tiene sus limitaciones. Puede utilizar la
FORMATMESSAGE()
función. Le permite formatear una cadena usando un formato similar a laprintf()
función en C.Sin embargo, la mayor limitación es que solo funcionará con mensajes en la tabla sys.messages. Aquí hay un artículo al respecto: microsoft_library_ms186788
Es una pena que no haya una manera más fácil de hacer esto, porque hay ocasiones en las que desea formatear una cadena / varchar en la base de datos. Con suerte, solo está buscando formatear una cadena de una manera estándar y puede usar la
sys.messages
tabla.Casualmente, también podría usar la
RAISERROR()
función con una gravedad muy baja, la documentación de raiseerror incluso menciona hacer esto, pero los resultados solo se imprimen. Por lo tanto, no podría hacer nada con el valor resultante (por lo que entiendo).¡Buena suerte!
fuente
FORMATMESSAGE()
es incorrecta, sin embargo es comprensible porque no está documentada pero aceptará cualquier cadena como primer parámetro, vea esta respuesta de @ g2server .El t-sql sin formato está limitado a CHARINDEX (), PATINDEX (), REPLACE () y SUBSTRING () para la manipulación de cadenas. Pero con sql server 2005 y versiones posteriores, puede configurar funciones definidas por el usuario que se ejecutan en .Net, lo que significa que configurar una UDF string.format () no debería ser demasiado difícil.
fuente
Una idea más.
Aunque esta no es una solución universal, es simple y funciona, al menos para mí :)
Para un marcador de posición {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
Para dos marcadores de posición {0} y {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
Para tres marcadores de posición {0}, {1} y {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
y así...
Este enfoque nos permite usar estas funciones en la instrucción SELECT y con parámetros de tipos de datos nvarchar, number, bit y datetime.
Por ejemplo:
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);
fuente
Creo que hay una pequeña corrección al calcular la posición final.
Aquí está la función correcta
**>>**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
fuente
Aquí está mi versión. Puede ampliarse para adaptarse a más parámetros y puede ampliar el formato según el tipo. Actualmente, solo se formatean los tipos de fecha y fecha y hora.
Ejemplo:
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)
Salida:
Funciones:
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;
fuente
esto es lo que encontré con mis experimentos usando el integrado
Función FORMATMESSAGE ()
sp_addmessage @msgnum=50001,@severity=1,@msgText='Hello %s you are #%d',@replace='replace' SELECT FORMATMESSAGE(50001, 'Table1', 5)
cuando llama sp_addmessage, su plantilla de mensaje se almacena en la tabla del sistema master.dbo.sysmessages (verificado en SQLServer 2000).
Debe administrar la adición y eliminación de cadenas de plantilla de la tabla usted mismo, lo cual es incómodo si todo lo que realmente desea es enviar un mensaje rápido a la pantalla de resultados.
La solución proporcionada por Kathik DV parece interesante pero no funciona con SQL Server 2000, así que la modifiqué un poco y esta versión debería funcionar con todas las versiones de 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
Uso:
print dbo.formatString('hello {0}... you are {1}','world,good') --result: hello world... you are good
fuente
Por el momento, esto no existe realmente (aunque, por supuesto, puede escribir el suyo). Hay un error de conexión abierta para él: https://connect.microsoft.com/SQLServer/Feedback/Details/3130221 , que al momento de escribir este artículo tiene solo 1 voto.
fuente
En realidad, no hay una función incorporada similar a la cadena. La función de formato de .NET está disponible en el servidor SQL.
Hay una función FORMATMESSAGE () en el servidor SQL pero imita la función printf () de C, no la función string.Format de .NET.
SELECT FORMATMESSAGE('This is the %s and this is the %s.', 'first variable', 'second variable') AS Result
fuente
No exactamente, pero vería algunos de los artículos sobre manejo de cadenas (entre otras cosas) de "Phil Factor" (¿geddit?) En Simple Talk.
fuente
este es un mal enfoque. Debería trabajar con dll de ensamblaje, en los que hará lo mismo por usted con un mejor rendimiento.
fuente