rowterminator - Inserción masiva, SQL Server 2000, linebreaks de Unix
rowterminator sql (8)
Me sentí obligado a contribuir ya que tenía el mismo problema, y necesito leer 2 archivos UNIX de SAP al menos un par de veces al día. Por lo tanto, en lugar de usar unix2dos, necesitaba algo con menos intervención manual y más automático a través de la programación.
Como se indicó, el Char (10) funciona dentro de la cadena sql. No quería usar una cadena sql, así que usé '''' '''' + Char (10) + '''' '''', pero por alguna razón, esto no compiló.
Lo que funcionó muy bien fue: con (ROWTERMINATOR = ''0x0a'')
Problema resuelto con Hex!
Espero que esto ayude a alguien.
Estoy tratando de insertar un archivo .csv en una base de datos con saltos de línea Unix. El comando que estoy ejecutando es:
BULK INSERT table_name
FROM ''C:/file.csv''
WITH
(
FIELDTERMINATOR = '','',
ROWTERMINATOR = ''/n''
)
Si convierto el archivo en formato de Windows, la carga funciona, pero no quiero hacer este paso adicional si puede evitarse. ¿Algunas ideas?
Me parece que hay dos vías generales que se pueden tomar: alguna forma alternativa de leer el CSV en el script SQL o convertir el CSV de antemano con cualquiera de las numerosas maneras en que puede hacerlo (bcp, unix2dos, si es uno) tiempo rey de una cosa, probablemente incluso puedas usar tu editor de código para arreglar el archivo por ti).
¡Pero tendrás que dar un paso extra!
Si este SQL se inicia desde un programa, es posible que desee convertir los finales de línea en ese programa. En ese caso, y usted decide codificar la conversión usted mismo, esto es lo que necesita tener en cuenta: 1. El final de la línea podría ser / n 2. o / r / n 3. o incluso / r (Mac!) 4. buena pena, podría ser que algunas líneas tienen / r / n y otras / n, cualquier combinación es posible a menos que controle de dónde proviene el CSV
BIEN BIEN. La posibilidad 4 es descabellada. Sucede en el correo electrónico, pero esa es otra historia.
Todo se reduce a esto. Unix usa LF (ctrl-J), MS-DOS / Windows usa CR / LF (ctrl-M / Ctrl-J).
Cuando usa ''/ n'' en Unix, se traduce a un personaje LF. En MS-DOS / Windows se traduce a CR / LF. Cuando su importación se ejecuta en el archivo formateado Unix, solo ve una LF. Por lo tanto, a menudo es más fácil ejecutar el archivo a través de unix2dos primero. Pero como dijiste en tu pregunta original, no quieres hacer esto (supongo que hay una buena razón por la que no puedes).
¿Por qué no puedes hacer eso?
(ROWTERMINATOR = CHAR(10))
Probablemente porque cuando se analiza el código SQL, no reemplaza el carácter char (10) con el carácter LF (porque ya está encerrado entre comillas simples). O tal vez se interpreta como:
(ROWTERMINATOR =
)
¿Qué sucede cuando haces eco de los contenidos de @bulk_cmd?
Una opción sería usar bcp y configurar un archivo de control con ''/n''
como el carácter de salto de línea.
Aunque ha indicado que preferiría no hacerlo, otra opción sería usar unix2dos para procesar previamente el archivo en uno con ''/r/n''
saltos de línea.
Finalmente, puede usar la opción FORMATFILE
en BULK INSERT
. Esto usará un archivo de control bcp para especificar el formato de importación.
Yo pensaría que "ROWTERMINATOR = ''/ n''" funcionaría. Sugeriría abrir el archivo en una herramienta que muestre "caracteres ocultos" para asegurarse de que la línea se termine como usted piensa. Yo uso Notepad ++ para cosas como esta.
¡Es un poco más complicado que eso! Cuando le dice a SQL Server ROWTERMINATOR = ''/ n'' esto lo interpreta como el terminador de fila predeterminado en Windows que en realidad es "/ r / n" (usando la notación C / C ++). Si el terminador de fila realmente es "/ n", deberá usar el SQL dinámico que se muestra arriba. ¡Acabo de pasar la mayor parte de una hora averiguando por qué / n realmente no significa / n cuando se usa con BULK INSERT!
Gracias a todos los que respondieron pero encontré mi solución preferida.
Cuando le dice a SQL Server ROWTERMINATOR = ''/ n'' esto lo interpreta como el terminador de fila predeterminado en Windows que en realidad es "/ r / n" (usando la notación C / C ++). Si el terminador de fila realmente es simplemente "/ n", deberá usar el SQL dinámico que se muestra a continuación.
DECLARE @bulk_cmd varchar(1000)
SET @bulk_cmd = ''BULK INSERT table_name
FROM ''''C:/file.csv''''
WITH (FIELDTERMINATOR = '''','''', ROWTERMINATOR = ''''''+CHAR(10)+'''''')''
EXEC (@bulk_cmd)
Por qué no puedes decir BULK INSERT ... (ROWTERMINATOR = CHAR (10)) está más allá de mí. No parece que pueda evaluar expresiones en la sección CON del comando.
Lo que hace arriba es crear una cadena del comando y ejecutar eso. Evitando cuidadosamente la necesidad de crear un archivo adicional o seguir pasos adicionales.
Confirmo que la sintaxis
ROWTERMINATOR = ''''''+CHAR(10)+''''''
funciona cuando se usa con un comando EXEC.
Si tiene varios caracteres de ROWTERMINATOR (por ejemplo, un conducto y un salto de línea de Unix), la sintaxis para esto es:
ROWTERMINATOR = ''''''+CHAR(124)+''''+CHAR(10)+''''''