Tengo una columna de SQL Server 2008 R2 que contiene una cadena que necesito dividir por una coma. He visto muchas respuestas en StackOverflow pero ninguna de ellas funciona en R2. Me aseguré de tener permisos de selección en cualquier ejemplo de función dividida. Cualquier ayuda muy apreciada.
sql
sql-server
tsql
sql-server-2008
split
Lee Grindon
fuente
fuente
mdq.RegexSplit
función en el complemento "Master Data Services", que puede ayudar. Ciertamente vale la pena investigar .Respuestas:
He usado este SQL antes, que puede funcionar para usted:
y para usarlo: -
fuente
En lugar de CTE recursivos y bucles while, ¿alguien ha considerado un enfoque más basado en conjuntos? Tenga en cuenta que esta función se escribió para la pregunta, que se basó en SQL Server 2008 y coma como delimitador . En SQL Server 2016 y superior (y en el nivel de compatibilidad 130 y superior),
STRING_SPLIT()
es una mejor opción .Si desea evitar que la longitud de la cadena sea <= el número de filas en
sys.all_columns
(9,980 pulgadasmodel
en SQL Server 2017; mucho más alto en sus propias bases de datos de usuarios), puede usar otros enfoques para derivar los números, como construyendo tu propia tabla de números . También podría usar un CTE recursivo en los casos en que no pueda usar tablas del sistema o crear las suyas propias:Pero deberá agregar
OPTION (MAXRECURSION 0)
(oMAXRECURSION <longest possible string length if < 32768>
) a la consulta externa para evitar errores con recursividad para cadenas> 100 caracteres. Si esa tampoco es una buena alternativa, vea esta respuesta como se señala en los comentarios.(Además, el delimitador tendrá que ser
NCHAR(<=1228)
. Todavía estoy investigando por qué).Más información sobre las funciones divididas, por qué (y prueba de ello) mientras que los bucles y los CTE recursivos no se escalan, y mejores alternativas, si las cadenas de división provienen de la capa de aplicación:
fuente
sys.all_objects
es menor que el número de caracteres en la cadena de entrada, truncará la cadena y los valores se perderán. Comosys.all_objects
solo se está utilizando como un truco para generar filas, existen mejores formas de hacerlo, por ejemplo, esta respuesta .Finalmente, la espera ha terminado en SQL Server 2016 , han introducido la función de cadena dividida:
STRING_SPLIT
Todos los demás métodos para dividir cadenas como XML, tabla de conteo, bucle, etc., han quedado asombrados por esta
STRING_SPLIT
función.Aquí hay un excelente artículo con comparación de rendimiento: Sorpresas y supuestos de rendimiento: STRING_SPLIT
fuente
La forma más fácil de hacerlo es mediante el
XML
formato.1. Convertir cadenas a filas sin tabla
CONSULTA
RESULTADO
2. Convertir a filas de una tabla que tiene una ID para cada fila CSV
TABLA DE FUENTES
CONSULTA
RESULTADO
fuente
@String
contiene caracteres prohibidos ... Acabo de publicar una respuesta para superar este problema.Necesitaba una manera rápida de deshacerse de la
+4
de un código postal .Sin proceso ... sin UDF ... solo un pequeño comando en línea que hace lo que debe hacer. No es lujoso, no elegante.
Cambie el delimitador según sea necesario, etc., y funcionará para cualquier cosa.
fuente
si reemplazas
con
¡puedes eliminar esa última inserción después del ciclo while!
fuente
+1
queSELECT @pos = LEN(@stringToSplit)
aparece para abordar esa cuestión. Sin embargo,SELECT @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, LEN(@stringToSplit)-@pos)
volverá aInvalid length parameter passed to the LEFT or SUBSTRING function
menos que agregue también+1
al tercer parámetro de SUBSTRING. o puede reemplazar esa tarea conSET @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, 4000) --MAX len of nvarchar is 4000
Todas las funciones para la división de cadenas que utilizan algún tipo de bucle (iteraciones) tienen un mal rendimiento. Deben reemplazarse con una solución basada en conjuntos.
Este código se ejecuta excelente.
fuente
@List
contiene caracteres prohibidos ... Acabo de publicar una respuesta para superar este problema.El enfoque de uso frecuente con elementos XML se rompe en caso de caracteres prohibidos. Este es un enfoque para usar este método con cualquier tipo de carácter, incluso con el punto y coma como delimitador.
El truco es, primero, usar
SELECT SomeString AS [*] FOR XML PATH('')
para que todos los personajes prohibidos escapen adecuadamente. Esa es la razón por la cual reemplazo el delimitador a un valor mágico para evitar problemas con el;
delimitador.El resultado
fuente
Tuve que escribir algo como esto recientemente. Aquí está la solución que se me ocurrió. Está generalizado para cualquier cadena de delimitador y creo que funcionaría un poco mejor:
fuente
Una solución usando un CTE, si alguien lo necesita (aparte de mí, quién obviamente lo hizo, por eso lo escribí).
fuente
Esto es más estrictamente adaptado. Cuando hago esto, generalmente tengo una lista delimitada por comas de identificadores únicos (INT o BIGINT), que quiero convertir como una tabla para usar como una unión interna a otra tabla que tiene una clave primaria de INT o BIGINT. Quiero que se devuelva una función con valores de tabla en línea para que tenga la combinación más eficiente posible.
El uso de la muestra sería:
Robé la idea de http://sqlrecords.blogspot.com/2012/11/converting-delimited-list-to-table.html , cambiándola para que tenga un valor de tabla en línea y se convierta en INT.
fuente
Hay una versión correcta aquí, pero pensé que sería bueno agregar un poco de tolerancia a fallas en caso de que tengan una coma final, así como hacerlo para que pueda usarlo no como una función sino como parte de un código más grande . En caso de que solo lo use una vez y no necesite una función. Esto también es para enteros (que es para lo que lo necesitaba), por lo que es posible que tenga que cambiar sus tipos de datos.
fuente
SET @StringToSeperate = @StringToSeperate+','
hiciera inmediatamente antes delWHILE
ciclo, creo que podría eliminar el bloque "agregar último valor". Vea también mi solución en githubModifiqué un poco la función de Andy Robinson. Ahora puede seleccionar solo la parte requerida de la tabla de retorno:
SELECT Name FROM dbo.splitstring('ELIS.YD.CRP1.1.CBA.MDSP.T389.BT') WHERE numOrder=5
fuente
Si necesita una solución rápida ad-hoc para casos comunes con un código mínimo, este CTE recursivo de dos líneas lo hará:
Use esto como una declaración independiente o simplemente agregue los CTE anteriores a cualquiera de sus consultas y podrá unirse a la tabla resultante
b
con otros para usar en cualquier otra expresión.editar (por Shnugo)
Si agrega un contador, obtendrá un índice de posición junto con la Lista:
El resultado:
fuente
Tomo la ruta xml envolviendo los valores en elementos (M pero todo funciona):
fuente
Aquí hay una versión que puede dividirse en un patrón usando patindex, una simple adaptación de la publicación anterior. Tuve un caso en el que necesitaba dividir una cadena que contenía múltiples caracteres separadores.
el resultado se ve así
stringa stringb x y z
fuente
Personalmente uso esta función:
fuente
He desarrollado un divisor doble (toma dos caracteres divididos) como se solicitó aquí . Podría ser de algún valor en este hilo, ya que es el más referenciado para consultas relacionadas con la división de cadenas.
Uso:
Uso posible (Obtenga el segundo valor de cada división):
fuente
Aquí hay un ejemplo que puede usar como función o también puede poner la misma lógica en el procedimiento. --SELECT * from [dbo] .fn_SplitString;
fuente
@vCSV
contiene caracteres prohibidos ... Acabo de publicar una respuesta para superar este problema.Una solución recursiva basada en cte
fuente
Esto se basa en la respuesta de Andy Robertson, necesitaba un delimitador distinto de la coma.
Y para usarlo:
(Probado en SQL Server 2008 R2)
EDITAR: código de prueba correcto
fuente
/ *
Casos de prueba: ver URL referenciada como "funcionalidad mejorada" arriba
SELECT *,LEN(Item+'_')-1 'L' from splitstring('a,,b')
SELECT *,LEN(Item+'_')-1 'L' from splitstring('a,,')
SELECT *,LEN(Item+'_')-1 'L' from splitstring('a,, ')
SELECT *,LEN(Item+'_')-1 'L' from splitstring('a,, c ')
* /
fuente
fuente
Puedes usar esta función:
fuente
Con el debido respeto a @AviG, esta es la versión libre de errores de la función que le ha devuelto para devolver todos los tokens en su totalidad.
fuente
La forma más fácil:
Funciona incluso en edición express :).
fuente