charindex - varchar sql
¿Cómo ejecutar una declaración SQL de más de 8000 caracteres desde una variable? (11)
Puedo usar el siguiente código para pequeñas consultas:
DECLARE @sql VARCHAR(8000)
SET @sql = ''SELECT * FROM myTable''
Exec @sql
El método anterior es muy útil para mantener grandes cantidades de código, especialmente cuando necesitamos hacer cambios una vez y tenerlos reflejados en todas partes.
Mi problema es que mi consulta (solo es una única consulta) de que quiero ingresar a la variable @sql utiliza más de 25 combinaciones de tablas, algunas de ellas en variables de tablas temporales, incorpora operaciones complejas y, por lo tanto, tiene más de 8000 caracteres. .
Deseaba usar el tipo de datos TEXTO para almacenar esta consulta, pero MSDN muestra un mensaje de advertencia de que Microsoft planea eliminar los tipos de datos de Texto, NText e Imagen de sus próximas versiones. Deseo que mi código se ejecute en el futuro también.
Pensé en almacenar esta consulta en un archivo separado, pero como utiliza uniones en las variables de la tabla y otros parámetros específicos del procedimiento, dudo que esto sea posible.
Por favor, dígame un método para almacenar una consulta grande en una variable y ejecutarla varias veces en un procedimiento.
El problema es con la conversión implícita.
Si tiene valores de Unicode / nChar / nVarChar que está concatenando, entonces SQL Server convertirá implícitamente su cadena a VarChar (8000), y desafortunadamente es demasiado tonto para darse cuenta de que truncará su cadena o incluso le advertirá que los datos han sido ¡Truncado para esa materia!
Cuando concatene cadenas largas (o cadenas que cree que podrían ser largas), siempre concicine previamente la creación de cadenas con CAST ('''' como nVarChar (MAX)) de esta forma:
SET @Query = CAST('''' as nVarChar(MAX))--Force implicit conversion to nVarChar(MAX)
+ ''SELECT...''-- some of the query gets set here
+ ''...''-- more query gets added on, etc.
Qué dolor y miedo es pensar cómo funciona SQL Server. :(
Conozco otras soluciones alternativas en la web que dicen dividir su código en múltiples asignaciones SET / SELECT utilizando múltiples variables, pero esto no es necesario dada la solución anterior.
Para aquellos que alcanzaron un máximo de 4000 caracteres, probablemente fue porque tenías Unicode, por lo que se convirtió implícitamente a nVarChar (4000).
Explicación:
Lo que está sucediendo detrás de la escena es que aunque la variable que está asignando se utiliza (MAX), SQL Server evaluará el lado derecho del valor que está asignando primero y predeterminado a nVarChar (4000) o VarChar (8000) (dependiendo de en lo que estás concatenando). Una vez que haya terminado de calcular el valor (y después de truncarlo por usted), lo convierte a (MAX) cuando se lo asigna a su variable, pero para entonces ya es demasiado tarde.
Bueno, me encontré con esto antes (en SQL 2005) y puedo decirle que tiene dos opciones:
1 - Utilice el procedimiento almacenado sys.sp_sqlexec que puede tomar un parámetro de texto de tipo (OMI: este es el camino a seguir). No me importa la advertencia. En SQL 2008 todavía se admite ntext, y si realiza la operación varchar (max) allí, funcionará. Básicamente, si tiene 2008, tanto la solución de texto como la varchar (max) funcionarán, por lo que tendrá tiempo para cambiarlo = -). Sin embargo, en 2012 solo funcionará varchar (max), por lo tanto, tendrá que cambiarlo antes de actualizar.
2- (Esto es lo que hice al principio) Revise ESTA publicación: http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=52274 y haga lo que dice el usuario "Kristen". Trabajó como un encanto para mí. No te olvides de preajustarlos en una cadena vacía. Si entendiste mi publicación, ya sabes que en SQL 2008 o más reciente es una tontería hacer esto.
Debería leer la respuesta de esta publicación que explica muy bien la situación: SQL NVARCHAR y VARCHAR Limits
- Si la longitud x de su cadena tiene menos de 4000 caracteres, una cadena se transformará en
nvarchar(x)
- Si la longitud y está entre 4000 y 8000,
varchar(y)
- Si la longitud es más de 8000 caracteres,
nvarchar(max)
que puede almacenar hasta 2 GB.
El problema es que nvarchar(max) + varchar(y) = nvarchar(max) + nvarchar(4000)
; SQL convertirá su varchar(y)
en nvarchar(y)
o nvarchar(4000)
si y es mayor que 4000 y menor que 8000, ¡truncando su cadena!
El problema es porque su cadena tiene un límite de 8000 símbolos por defecto. Para evitar esto debes convertirlo a (N) VARCHAR (MAX)
DECLARE @sql VARCHAR(8000)
SET @sql = CAST(''SELECT * FROM myTable'' AS VARCHAR(MAX))
--Check length of variable
PRINT ''Length is: ''+CAST(LEN(@sql) AS VARCHAR)+ ''symbols''
Exec @sql
He estado teniendo el mismo problema, con las cuerdas truncadas. Aprendí que puedes ejecutar la sentencia sp_executesql varias veces.
Como mi bloque de código superó el límite de 4k / Max, lo dividí en pequeños fragmentos como este:
set @statement = ''
update pd
set pd.mismatchtype = 4
FROM [E].[dbo].['' + @monthName + ''_P_Data] pd
WHERE pd.mismatchtype is null ''
exec sp_executesql @statement
set @statement = ''Select * from xxxxxxx''
exec sp_executesql @statement
set @statement = ''Select * from yyyyyyy ''
exec sp_executesql @statement
end
Entonces, cada conjunto @Statement puede tener el valor varchar (max) siempre que cada fragmento esté dentro del límite de tamaño (elimino el código real en mi ejemplo, por razones de ahorro de espacio)
No hay una solución para esto en el camino en que lo estás haciendo. MsSql a partir de 2012 admite Ntext, por ejemplo, que le permite ir más allá de 8000 caracteres en una variable. La forma de resolver esto es crear varias variables o filas en una tabla que pueda recorrer en iteración.
En el mejor de los casos con una versión MsSql, el tamaño máximo de una variable es de 8000 caracteres en la versión más reciente desde que se escribió esto. Así que si estás tratando con una cadena de 80,000 caracteres. Puede analizar los datos en diez variables de 8000 caracteres cada una (8000 x 10 = 80,000) o puede cortar la variable en pedazos y ponerla en una tabla, digamos Tabla de tabla larga (Bigstring Varchar (8000)), inserte 10 filas en esta y use una Valor de identidad para que pueda recuperar los datos en el mismo orden.
El método que está intentando no funcionará con MsSql actualmente.
Otra opción oscura que funcionará pero no es aconsejable es almacenar la variable en un archivo de texto usando comandos de shell de comandos para leer / escribir el archivo. Entonces tienes espacio disponible para ti más allá de 8000 caracteres. Esto es lento y menos seguro que los otros métodos descritos anteriormente.
Si está en SQL Server 2008 o más reciente, puede usar VARCHAR (MAX)
DECLARE @sql VARCHAR(MAX)
Tuve el mismo problema. Tengo un SQL que tenía más de 21,000 caracteres. Por alguna razón,
Declare @SQL VARCHAR(MAX)
EXEC(@SQL)
surgiría con varios problemas
Finalmente tuve que dividirlo en múltiples variables por igual y luego funcionó.
Declare @SQL1 VARCHAR(MAX) = ''First Part''
Declare @SQL2 VARCHAR(MAX) = ''Second Part''
Declare @SQL3 VARCHAR(MAX) = ''Third Part''
Declare @SQL4 VARCHAR(MAX) = ''Fourth Part''
Set @SQL= @SQL1 + @SQL2 + @SQL3 + @SQL4
EXEC(@SQL)
utilizar
EXEC
(
''
--your sql script here
''
)
ALTER PROCEDURE [dbo].[spGetEmails]
AS
BEGIN
SET NOCOUNT ON;
-- Insert statements for procedure here
declare @p varbinary(max)
set @p = 0x
declare @local table (col text)
SELECT @p = @p + 0x3B + CONVERT(varbinary(100), Email)
FROM tbCarsList
where email <> ''''
group by email
order by email
set @p = substring(@p, 2, 10000000)
insert @local values(cast(@p as varchar(max)))
select col from @local
END
DECLARE @sql VARCHAR(max)
SET @sql = ''SELECT * FROM myTable''
Exec @sql
Nota:
Print(@sql)
¡Solo muestra los primeros 8000 caracteres!