Pregunta

Estoy usando BCP para cargar una tabla de un archivo CSV exportado de otra mesa por otra persona muy, muy lejos, y se han encontrado con algunos problemas. Mis originales dos problemas: un campo exportado es un entero que tiene que llegar en un campo varchar, y otras necesidades sobre el terreno a ocupar con una cadena estática. Bueno, la primera es nada del otro mundo, y la respuesta de Chad me llevó a la sintaxis @{n='Col3';e={'ABC'}}. Pero estoy dando tumbos varios problemas para conseguir los datos cargados correctamente.

  1. A veces un valor podría no tener espacios, a veces puede. ¿Cómo se especifica delimitadores para que en un archivo de formato BCP? Lo pregunto porque, presumiblemente, lo que necesito para rodear estos con comillas.

    a. ¿Debo ser valores de envoltura en el archivo CSV intermedia con citas?

  2. En mi código de prueba, que está empujando a los encabezados de columna y un salto de línea en Col1 con el valor real de Col1 para la primera fila.

  3. En mi código real, no desinfectadas, me estoy poniendo String data, right truncation en la primera fila, aunque la segunda fila se inserta bien.

En cualquier caso, los datos iniciales CSV que recibo de miradas en otros lugares como este (nota: no hay línea de encabezamiento)

"ABC123",123456,"APPLE"
"XYZ789",456789,"ORANGE"

La tabla de SQL de destino es como esto

Col1 varchar(50) (Primary Key)
Col2 varchar(50)
Col3 varchar(50)
Col4 varchar(50)

Es necesario cargar ABC123 en Col1, 123456 en Col2, Export1 en Col3, y Apple en Col4. Export1 es la cadena estática. Estoy haciendo esto en PowerShell 1.0.

EDIT: Import-CSV de Chad | miradas Export-CSV prometedor, pero que no le gustan los encabezados que falta, y PS 1.0 no soporta la opción -Header.

EDIT: Descripción Editado por encima de reflejar la forma en que he vagado a este punto. La tabla de cuatro columnas y CSV de tres columnas son obviamente simplificaciones. Una columna real es una ciudad, por lo que podría contener cadenas simples o aquellos que requieren citando. Mi Powershell 1.0 código en este punto es el siguiente.

$SQLSERVER="svr"
$SQLTABLE="test"
$SQLUSER="u"
$SQLPASS="p"

$TESTFILE = "testdata.csv"
$TESTFILEHDR = "testdata-wHeaders.csv"
$TESTFILEFIX = "testdata-fixed.csv"
$OrigHeaders = "`"Col1`",`"Col2`",`"Col3`"`n"

function Create-BcpFormat($fileName)
{
@"
<?xml version='1.0'?>
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <RECORD>
  <FIELD ID='1' xsi:type='CharTerm' TERMINATOR=',"' COLLATION='SQL_AltDiction_CP850_CI_AS'/>
  <FIELD ID='2' xsi:type='CharTerm' TERMINATOR='",' COLLATION='SQL_AltDiction_CP850_CI_AS'/>
  <FIELD ID='3' xsi:type='CharTerm' TERMINATOR=',' COLLATION='SQL_AltDiction_CP850_CI_AS'/>
  <FIELD ID='4' xsi:type='CharTerm' TERMINATOR='\r\n' COLLATION='SQL_AltDiction_CP850_CI_AS'/>
 </RECORD>
 <ROW>
  <COLUMN SOURCE="1" NAME="Col1" xsi:type="SQLVARYCHAR"/>
  <COLUMN SOURCE="2" NAME="Col2" xsi:type="SQLVARYCHAR"/>
  <COLUMN SOURCE="3" NAME="Col3" xsi:type="SQLVARYCHAR"/>
  <COLUMN SOURCE="4" NAME="Col4" xsi:type="SQLVARYCHAR"/>
 </ROW>
</BCPFORMAT>
"@ | Set-Content $filename
}

## GHI456 is already in the table, clean out previous attempts
"`nclean test table:"
osql @("-S","$SQLSERVER","-U","$SQLUSER","-P","$SQLPASS","-Q",
    """delete from $SQLTABLE where col1 <> 'GHI456' or col1 is null""")

## Prepend
$body = [string]::join([environment]::NewLine, (gc $TESTFILE))
$OrigHeaders + $body > $TESTFILEHDR

"`nTESTFILEHDR:"
type $TESTFILEHDR

$accts = Import-csv $TESTFILEHDR | select 'Col1', 'Col2', @{n='Col3';e={'ABC'}}, @{n='Col4';e={$_.Col3}}
$accts
$accts | Export-Csv $TESTFILEFIX -NoTypeInfo

"`nTESTFILEFIX:"
type $TESTFILEFIX

$BCPFMTFILE = "bcp.fmt"
$BCPERRFILE = "bcp.err"
Create-BcpFormat $BCPFMTFILE
bcp @("$SQLTABLE","in","$TESTFILEFIX","-S","$SQLSERVER","-U","$SQLUSER","-P","$SQLPASS","-f",$BCPFMTFILE,"-e",$BCPERRFILE)
Remove-Item $BCPFMTFILE

"`ntest table:"
osql @("-S","$SQLSERVER","-U","$SQLUSER","-P","$SQLPASS","-Q",
    """select left(Col1,20) 'Col1', left(Col2,8) 'Col2', left(Col3,8) 'Col3', left(Col4,8) 'Col4' from $SQLTABLE""")

"`nBCPERRFILE:"
type $BCPERRFILE
¿Fue útil?

Solución

¿Por qué no utilizar SqlBulkCopy de ADO.NET mediante programación en PowerShell? Usted tendrá el control total: línea de lectura por línea, conversión de los datos y rellenar un DataTable como desee e invocar WriteToServer en lotes. Ver http://msdn.microsoft.com/en -us / biblioteca / system.data.sqlclient.sqlbulkcopy.aspx

Otros consejos

Se podría hacer algo como esto para añadir la columna

Import-CSV \ forum.csv -Header "Col1", "Col2", "Col4". | Seleccione Col1, Col2, @ {n = 'Col3'; e = { 'Export1'}}, Col4 | Export-CSV ./forum2.csv -NoTypeInfo

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top