2010-11-23 14 views
7

Estoy tratando de cargar un archivo donde todas las líneas usan las mismas reglas. (Asumir CABECERA es una sola línea)MySQL: cómo cargar datos con formato de fila fija en variables de usuario

HEADER1 
HEADER2 
....... 

Pero desgraciadamente cuando trato de utilizar la instrucción LOAD DATA INFILE consigo este error: Código de error : 1409 No se puede cargar valor a partir de los archivos de tamaño fijo filas a la variable.

Este es el código que he escrito:

USE test; 
DROP TABLE IF EXISTS EXAMPLE_H; 
CREATE TABLE EXAMPLE_H(
    ID CHAR(20), 
    SP CHAR(3), 
    IVA CHAR(11) PRIMARY KEY, 
    NLP CHAR(6), 
    DLP DATE, 
    DUVI DATE, 
    DELP CHAR(30), 
    FILLER CHAR(39), 
    VTLP CHAR(3), 
    FILL CHAR(49) 
); 

LOAD DATA INFILE 'BTILSP.TXT' 
    INTO TABLE test.EXAMPLE_H 
    FIELDS TERMINATED BY '' 
    LINES TERMINATED BY '\n' 
    (ID, SP, IVA, NLP, @var_date_one, @var_date_two, DELP, FILLER, VTLP, FILL) 
    SET DLP = str_to_date(@var_date_one, '%Y%m%d', 
     DUVI = str_to_date(@var_date_two, '%Y%m%d'); 

Tenía la idea de la lectura de la parte inferior de this page (comentario de Ramam Pullella), y me encontré con el mismo se explica en algunos sitios web, pero no puedo entender por qué estoy recibiendo este error

Si no utilizo las variables @var_date_one y @var_date_two, por lo que la función STR_TO_DATE, la fecha no se representa como necesita MySql - la fecha en el archivo es algo así como "20100701" - entonces ese campo contener todos los ceros o una fecha diferente a la que estoy esperando. Si cambio DLP y DUVI para que sean representados por CHAR (8), entonces funciona, pero no usaré las comparaciones SQL DATE y herramientas similares.

¿Me puede ayudar por favor? :) Muchas gracias.

EDIT:

Parece que el problema viene dado por la línea SUSPENDIDO POR '', ya que este tipo de línea es una "fila fijo (no delimitada)". Tal vez no se puede asignar a la variable por un motivo desconocido, pero es de esta manera que funciona. La documentación dice:

User variables cannot be used when loading data with fixed-row format because user variables do not have a display width.

Cualquier sugerencia?

RE-EDIT: He leído el comentario de Ryan Neve en la parte inferior de esa página. Él da un truco para leer filas fijos en variables:

LOAD DATA LOCAL INFILE '<file name>' INTO TABLE <table> 
(@var1) 
SET Date=str_to_date(SUBSTR(@var1,3,10),'%m/%d/%Y'), 
Time=SUBSTR(@var1,14,8), 
WindVelocity=SUBSTR(@var1,26,5), 
WindDirection=SUBSTR(@var1,33,3), 
WindCompass=SUBSTR(@var1,38,3), 
WindNorth=SUBSTR(@var1,43,6), 
WindEast=SUBSTR(@var1,51,6), 
WindSamples=SUBSTR(@var1,61,4); 

¿Cree que es una buena manera de hacerlo? :)

+2

En documentos indican que no va a funcionar para los datos de formato de longitud fija. Lo mejor, es volver a actualizar su archivo de inserción. O cámbielo a varchar, y realice una conversión de tipo más tarde. – ajreal

+0

@ajreal: ¡gracias! Ayer no leí tu respuesta, pero edité mi pregunta y escribí algo así como lo que dijiste :) – Markon

Respuesta

3

No soy un experto, pero me parece que si los campos terminan con una cadena vacía, entonces tienen que ser de tamaño fijo; tiene que haber alguna manera de determinar los límites entre los campos, y si no hay terminador, entonces tienen que ser de tamaño fijo.

observo que el manual MySQL 5.5 dice:

  • User variables cannot be used when loading data with fixed-row format because user variables do not have a display width.

También (en lugar anteriormente en la página) dice:

  • If the FIELDS TERMINATED BY and FIELDS ENCLOSED BY values are both empty (''), a fixed-row (nondelimited) format is used. With fixed-row format, no delimiters are used between fields (but you can still have a line terminator). Instead, column values are read and written using a field width wide enough to hold all values in the field. For TINYINT, SMALLINT, MEDIUMINT, INT, and BIGINT, the field widths are 4, 6, 8, 11, and 20, respectively, no matter what the declared display width is.

Debido a que su declaración no tiene 'CAMPOS CERRADOS POR' y vacío ' CAMPOS CERRADOS POR ', es por eso que tienes un formato fijo. Y por lo tanto, no puedes hacer lo que quieras.


A veces, es más fácil masajear los datos fuera del DBMS; la reparación de los datos puede ser una de esas operaciones.Tengo un programa que llamo DBLDFMT que no he usado desde hace unos años, pero puede hacer una variedad de operaciones, como convertir números decimales con puntos decimales implícitos (un truco de mainframe, el campo de precio podría ser 0023199, representando el valor £ 231.99). También puede manejar manipulaciones de fechas (no necesariamente usando una notación especialmente fácil de usar, pero es capaz de lidiar con los problemas que enfrenté al obtener datos de mainframes en un DBMS de Unix, no en MySQL; no existía cuando escribí esto). . código Contacta conmigo si eso podría ser de cualquier interés - ver perfil

+0

Muchas gracias por tu respuesta. Sin embargo, resolví este problema ya que puedes leer en la parte inferior. – Markon

+1

@Markon: OK - entonces tal vez debería escribir su respuesta como respuesta, y luego aceptarla después de la demora requerida (3 días, pero no estoy seguro de si es a partir de la pregunta o la presentación de la suya propia responder). Eso logrará el cierre de la pregunta; no se mostrará como sin respuesta o sin una respuesta aceptada/vuelta arriba. –

+0

No me gusta demasiado la idea de responder a mis preguntas: P Por cierto, no puedo ver este requisito en las preguntas frecuentes. Si es el "procedimiento", está bien, entonces la próxima vez me responderé a mí mismo: P Gracias de nuevo :) – Markon

1

En caso de que alguien viene a través de este Si sólo ejecuta

LOAD DATA LOCAL INFILE '<file name>' INTO TABLE <table> (@var1) SET ...

sin especificar FIELDS TERMINATED BY, y el archivo contiene.. comas MySQL se dividirá en los predeterminados.

En tal caso, puede decirle a MySQL que su delimitador de campo es algo tonto. por ejemplo:

FIELDS TERMINATED BY '@@@@@@@@@@@@'

De esta manera toda la línea se puso en el primer "columna" es decir, la variable de usuario. Luego puede usarlo exactamente como se muestra en su código en la parte superior.

Vale la pena señalar trata MySQL delimitador de una cadena, por lo que puede incluso tener
FIELDS TERMINATED BY 'this_string_thoes_not_appear_in_my_file si quieres

+0

¡Gracias por compartir! – Markon

Cuestiones relacionadas