80 votes

ORA-01461 : possibilité de lier une valeur LONG uniquement pour l'insertion dans une colonne LONG - se produit lors d'une requête

Lorsque j'essaie d'interroger des objets, j'obtiens l'erreur suivante :

ORA-01461: can bind a LONG value only for insert into a LONG column

Quelqu'un pourrait-il m'aider à trouver la cause et la solution du problème ?

0 votes

@Rupesh êtes-vous sûr que cela provient d'une requête ? Essayez-vous de faire une insertion peut-être ? De plus, comment est-ce exécuté (java, C#, sqlplus, etc.) ?

1 votes

Il existe des solutions de contournement PL/SQL pour l'utilisation de chaînes de caractères longues pour l'insertion dans les fichiers suivants CLOB y BLOB colonnes.

0 votes

Pour la plupart des personnes qui cherchent une solution, celle-ci serait la bonne (et non la solution acceptée) : stackoverflow.com/a/14497831/1657465

1voto

Francisco M Points 113

Dans mon cas particulier, j'essayais de stocker un fichier codé en Base64 dans un champ BLOB d'une table, en utilisant Mybatis.

Donc dans mon xml j'avais :

<insert id="save..." parameterType="...DTO">
    <selectKey keyProperty="id" resultType="long" order="BEFORE">
        SELECT SEQ.nextVal FROM DUAL
    </selectKey>
    insert into MYTABLE(
        ID,
        ...,
        PDF
    ) values (
        #{id, jdbcType=VARCHAR},
        ...,
        #{tcPdf, jdbcType=BLOB},
    )
</insert>

et dans mon DTO :

String getPdf(){
    return pdf;
}

Cela fait que Mybatis menace comme s'il s'agissait d'une séquence de caractères de type String et essaie de la stocker comme un Varchar. Ma solution était donc la suivante :

Dans mon DTO :

Byte[] getPdf(){
    return pdf.getBytes();
}

Et ça a marché.

J'espère que cela pourra aider tout le monde.

0voto

J'ai rencontré le même problème en utilisant Siebel REXPIMP (importation de registre) lors de l'utilisation du dernier pilote Instant Client. Pour résoudre ce problème, utilisez plutôt le pilote Data Direct fourni par Siebel. La DLL est SEOR823.DLL

0voto

Vik Points 539

J'ajoute un autre cas d'utilisation où j'ai constaté que cela se produisait. J'utilisais une application ADF Fusion et le type de colonne utilisé était un varchar2(4000) qui ne pouvait pas contenir le texte, d'où cette erreur.

0voto

Jonathan L Points 1

J'ai une solution pour Java/JPA/eclipselink/oracle lorsque l'on insère une longue chaîne xml (>4000) dans une colonne XMLTYPE à l'adresse suivante Insérer un XML de plus de 4000 caractères dans une colonne Oracle XMLTYPE . Pour plus de clarté, nous reprenons ici le même contenu au cas où le lien ne fonctionnerait pas.

Vous devez d'abord convertir une chaîne xml de plus de 4000 caractères en type SQLXML.

Environnement : jpa 2.1.0, eclipselink 2.5.2, oracle db 11gr2

SQL :

CREATE TABLE "XMLTEST"
( "ID" NUMBER(10,0) NOT NULL ENABLE, 
  "DESCRIPTION" VARCHAR2(50 CHAR) NOT NULL ENABLE, 
  "XML_TXT" "XMLTYPE" NOT NULL ENABLE
);

INSERT INTO XMLTEST (ID, DESCRIPTION, XML_TXT) VALUES (101, 'XML DATA', '<data>TEST</data>');
COMMIT;

DROP TABLE "XMLTEST";

Code Java

String sql = "INSERT INTO XMLTEST (ID, DESCRIPTION, XML_TXT) VALUES (?, ?, ?)";
String xmlDataStr = "<data>test...</data>"; // a long xml string with length > 4000 characters
Connection con = getEntityManager().unwrap(Connection.class);
SQLXML sqlXml = con.createSQLXML();
sqlXml.setString(xmlDataStr);

Code Java - utilisation de PreparedStatement

PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setLong(1, 201);
pstmt.setLong(2, "Long XML Data");
pstmt.setSQLXML(3, sqlXml);
pstmt.execute();

Code Java - utilisation de la requête native au lieu de PreparedStatement

Query query = getEntityManager().createNativeQuery(sql);
query.setParameter(1, 301);
query.setParameter(2, "Long XML Data");
query.setParameter(3, sqlXml);
query.executeUpdate();

0voto

David Gausmann Points 747

J'ai eu le même problème en utilisant PHP et des instructions préparées sur une colonne VARCHAR2. Ma chaîne ne dépassait pas la taille de VARCHAR2. Le problème est que j'ai utilisé -1 comme longueur maximale pour la liaison, mais le contenu de la variable a changé par la suite.

En exemple :

$sMyVariable = '';
$rParsedQuery = oci_parse($rLink, 'INSERT INTO MyTable (MyVarChar2Column) VALUES (:MYPLACEHOLDER)');
oci_bind_by_name($rParsedQuery, ':MYPLACEHOLDER', $sMyVariable, -1, SQLT_CHR);

$sMyVariable = 'a';
oci_execute($rParsedQuery, OCI_DEFAULT);
$sMyVariable = 'b';
oci_execute($rParsedQuery, OCI_DEFAULT);

Si vous remplacez le -1 par la largeur maximale de la colonne (c'est-à-dire 254), ce code fonctionne. Avec -1, oci_bind_by_param utilise la longueur actuelle du contenu de la variable (dans mon cas 0) comme longueur maximale pour cette colonne. Il en résulte un ORA-01461 lors de l'exécution.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X