Précédent   Forum des professionnels en informatique > Bases de données > Firebird
Firebird Forum d'entraide sur le SGBD Firebird. Avant de poster -> F.A.Q Firebird, Tutoriels
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 23/02/2008, 22h33   #1
Membre régulier
 
Avatar de Suryavarman
 
Inscription : mai 2006
Messages : 159
Détails du profil
Informations personnelles :
Âge : 28

Informations forums :
Inscription : mai 2006
Messages : 159
Points : 99
Points : 99
Par défaut API C++ Firebird Requête CREATE TABLE.

J'utilise l'Embedded, j'ai interfacé la DLL ( j'utilise GCC sur windows donc pas de .a pour ma pomme ). J'utilise aussi wxwidget.

La création de la BD fonctionne mais je but à la création d'une table. Avant de la créer je vérifie si la table n'existe pas. Du moins c'est ce que j'espère réussir à faire faire.

L'erreur qu'il me sort : Invalid token -104
cela se produit exactement lors de l'appel de isc_dsql_execute_immediate
D'ailleurs la requête peut être simplement wxT(" CREATE TABLE " ) + aNameDoubleCote, il en ressort la même erreur.

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
 
bool GR_Firebird::CreateTable( wxString aNameTable, bool Commit )
{
 
    IF( m_baseAttache )
    {
        wxString aNameDoubleCote = wxT('"') + aNameTable + wxT('"')  ;
 
        wxString createTable = wxT( "IF NOT EXISTS ( SELECT name FROM sysobjects WHERE type='U' AND name = ") ;
        createTable += aNameDoubleCote + wxT(" ) ") ;
        createTable += wxT(" CREATE TABLE " ) +  aNameDoubleCote ;
 
        bool result = !GR_isc_start_transaction( m_status, &m_trans, 1, &m_db, 0, NULL ) ;
             result = result && !GR_isc_dsql_execute_immediate( m_status, &m_db, &m_trans, 0, createTable.c_str(), 1, NULL ) ;
 
        IF( result )
        {
 
            wxMessageBox( wxT( "Nouvelle table cree : " ) + aNameTable ) ;
 
            IF( Commit )
                GR_isc_commit_transaction( m_status, &m_trans ) ;
 
            RETURN true ;
 
        }
        else
        {
            wxLogError( wxT("Impossible de creer la table : ") + aNameTable + GetSqlErreur( m_status )  ) ;
        }
 
    }
 
    RETURN false ;
 
}
Merci de votre attention .
__________________
"Le pointeur Malkavien..ouiiiiii...c'est moiiiii"
Suryavarman est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/02/2008, 14h22   #2
Membre régulier
 
Avatar de Suryavarman
 
Inscription : mai 2006
Messages : 159
Détails du profil
Informations personnelles :
Âge : 28

Informations forums :
Inscription : mai 2006
Messages : 159
Points : 99
Points : 99
En regardant un peu mieux la documentation, l'option dialecte est sur les exemples à un. Mais si j'ai bien compris 1 correspond à interbase, 2 la migration entre interbase et firebird et 3 purement firebird. Donc j'ai essayé avec 3. Mais ça n'arrange rien.

J'ai essayé avec un create table avec le nom de la table en minuscule, en majuscule, sans double cotes etc etc. Toujours la même erreur.

Si cela peut aider, voici la documentation de isc_dsql_execute_immediate.

Citation:
isc_dsql_execute_immediate()
Prepares and executes just once a DSQL statement that does not return data. There is a
special case of isc_dsql_execute_immediate() for creating databases.
Syntax
ISC_STATUS isc_dsql_execute_immediate(
ISC_STATUS *status_vector,
isc_db_handle *db_handle,
isc_tr_handle *trans_handle,
unsigned short length,
char *statement,
unsigned short dialect,
XSQLDA *xsqlda);

Note In the special case where the statement is CREATE DATABASE, there is no transaction, so db_handle and trans_handle must be pointers to handles whose value is NULL. When isc_dsql_execute_immediate() returns, db_handle is a valid handle, just as though you had made a call to isc_attach_database().

Parameter Type Description
status_vector ISC_STATUS * Pointer to the error status vector
db_handle isc_db_handle *

• If statement is not CREATE DATABASE, this is a pointer to a database
handle set by a previous call to isc_attach_database(); db_handle
returns an error in status_vector if it is NULL

• If statement is CREATE DATABASE, this must point to a database
handle whose value is NULL
trans_handle isc_tr_handle *

• If statement is not CREATE DATABASE, this is a pointer to a
transaction handle whose value has been set by a previous
isc_start_transaction() call; trans_handle returns an error if NULL

• If statement is CREATE DATABASE or SET TRANSACTION, this must point
to a transaction handle whose value is NULL length unsigned short Length of the DSQL statement in bytes; set to 0 in C programs to indicate a null-terminated string
__________________
"Le pointeur Malkavien..ouiiiiii...c'est moiiiii"
Suryavarman est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/02/2008, 14h26   #3
Membre expérimenté
 
Inscription : mars 2002
Messages : 711
Détails du profil
Informations forums :
Inscription : mars 2002
Messages : 711
Points : 599
Points : 599
http://www.ibpp.org/
VLDG est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/02/2008, 14h44   #4
Membre régulier
 
Avatar de Suryavarman
 
Inscription : mai 2006
Messages : 159
Détails du profil
Informations personnelles :
Âge : 28

Informations forums :
Inscription : mai 2006
Messages : 159
Points : 99
Points : 99
Merci je connais.
__________________
"Le pointeur Malkavien..ouiiiiii...c'est moiiiii"
Suryavarman est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/02/2008, 18h52   #5
Expert Confirmé

 
Homme Philippe Makowski
Consultant spécialité Firebird
Inscription : mai 2002
Messages : 2 215
Détails du profil
Informations personnelles :
Nom : Homme Philippe Makowski
Âge : 49
Localisation : France

Informations professionnelles :
Activité : Consultant spécialité Firebird
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 2 215
Points : 3 318
Points : 3 318
un create table sans définition de colonne ????
il faut définir au moins une colonne
__________________
Philippe Makowski
IBPhoenix - Firebird
Membre de l'April
makowski est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/02/2008, 21h59   #6
Membre régulier
 
Avatar de Suryavarman
 
Inscription : mai 2006
Messages : 159
Détails du profil
Informations personnelles :
Âge : 28

Informations forums :
Inscription : mai 2006
Messages : 159
Points : 99
Points : 99
Bien vue :p Mici

Ça fonctionne sauf pour la partie avec le IF NOT EXISTS.
Mon petit doigt me dit que isc_dsql_execute_immediate étant prévu pour les requêtes sans résultat il doit pas aimer la partie avec le SELECT.
Je vais tester avec un simple isc_dsql_execute.
__________________
"Le pointeur Malkavien..ouiiiiii...c'est moiiiii"
Suryavarman est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/02/2008, 23h05   #7
Membre régulier
 
Avatar de Suryavarman
 
Inscription : mai 2006
Messages : 159
Détails du profil
Informations personnelles :
Âge : 28

Informations forums :
Inscription : mai 2006
Messages : 159
Points : 99
Points : 99
J'obtiens la même erreur en passant avec un isc_dsql_execute.
soit je fais quelque chose de travers avec les fonctions de l'API soit ma requête est bidon. (j'opte pour la requête )
__________________
"Le pointeur Malkavien..ouiiiiii...c'est moiiiii"
Suryavarman est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/02/2008, 10h10   #8
Expert Confirmé

 
Homme Philippe Makowski
Consultant spécialité Firebird
Inscription : mai 2002
Messages : 2 215
Détails du profil
Informations personnelles :
Nom : Homme Philippe Makowski
Âge : 49
Localisation : France

Informations professionnelles :
Activité : Consultant spécialité Firebird
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 2 215
Points : 3 318
Points : 3 318
Citation:
Envoyé par Suryavarman Voir le message
J'obtiens la même erreur en passant avec un isc_dsql_execute.
soit je fais quelque chose de travers avec les fonctions de l'API soit ma requête est bidon. (j'opte pour la requête )
ça oui
Code :
"IF NOT EXISTS ( SELECT name FROM sysobjects WHERE type='U' AND name = "
ne veux rien dire pour Firebird
il n'existe pas de table sysobjects
__________________
Philippe Makowski
IBPhoenix - Firebird
Membre de l'April
makowski est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/02/2008, 13h02   #9
Membre régulier
 
Avatar de Suryavarman
 
Inscription : mai 2006
Messages : 159
Détails du profil
Informations personnelles :
Âge : 28

Informations forums :
Inscription : mai 2006
Messages : 159
Points : 99
Points : 99
pas la peine que je le dise, mais bon je débute en sql.
Je vais chercher ce qu'il faut mettre à la place de sysobjects.

Merci makowski.

EDIT :
Je stocke les liens ici :
http://www.delphinaute.com/forum7/discussion68196/
DocFirbird->InterBase 6.0 Manuals->Language Reference-> System tables page 242 du pDF

EDIT:
Tien ça m'apprendra à m'endormir lors de la lecture de la fac
J'avais loupé ça
PROCEDURE STOCKE
__________________
"Le pointeur Malkavien..ouiiiiii...c'est moiiiii"
Suryavarman est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/02/2008, 21h14   #10
Membre régulier
 
Avatar de Suryavarman
 
Inscription : mai 2006
Messages : 159
Détails du profil
Informations personnelles :
Âge : 28

Informations forums :
Inscription : mai 2006
Messages : 159
Points : 99
Points : 99
Code :
SELECT DISTINCT RDB$GENERATOR_NAME FROM RDB$GENERATORS RG WHERE RG.RDB$GENERATOR_NAME = "aNameTable"
J'ai abouti à cette requête. Le principe est de récupérer le résultat de cette requête, si j'obtiens un SQLDA->sqld > 0 alors il y a une table qui existe sinon il y en a pas.

Ça c'est ma théorie, la pratique c'est qu'il me dit cette colonne n'existe pas dans cette table.
Citation:
Column does not belong to referenced table
LANGREF.pdf page 257
Citation:
RDB$GENERATORS

RDB$GENERATORS stores information about generators, which provide the ability to generate a unique identifier for a table.

Column name Datatype Length Description
RDB$GENERATOR_NAME CHAR 31 Name of the table to contain the unique identifier produced by the number generator
EDIT: En fait j'ai choisi par élimination. J'ai pas trouvé de table qui contienne explicitement les noms des tables.
__________________
"Le pointeur Malkavien..ouiiiiii...c'est moiiiii"
Suryavarman est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/02/2008, 21h54   #11
Expert Confirmé

 
Homme Philippe Makowski
Consultant spécialité Firebird
Inscription : mai 2002
Messages : 2 215
Détails du profil
Informations personnelles :
Nom : Homme Philippe Makowski
Âge : 49
Localisation : France

Informations professionnelles :
Activité : Consultant spécialité Firebird
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 2 215
Points : 3 318
Points : 3 318
Langref :
Citation:
RDB$RELATIONS
RDB$RELATIONS defines some of the characteristics of tables and views. Other
characteristics, such as the columns included in the table and a description of each
column, are stored in the RDB$RELATION_FIELDS table.
...
RDB$RELATION_NAME CHAR 31 The unique name of the table defined by this row
__________________
Philippe Makowski
IBPhoenix - Firebird
Membre de l'April
makowski est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/02/2008, 22h25   #12
Membre régulier
 
Avatar de Suryavarman
 
Inscription : mai 2006
Messages : 159
Détails du profil
Informations personnelles :
Âge : 28

Informations forums :
Inscription : mai 2006
Messages : 159
Points : 99
Points : 99
je pensais que c'était seulement les tables qui ont une relation qui se retrouvaient là dedans.

Je continu à déboguer, il devrait trouver la colonne RDB$RELATION_NAME mais c'est pas le cas.

Je dois avoir un soucis dans mes fonctions.

Je suis désolé d'être pas très doué, je dis ça car
http://interbase.developpez.com/faq/...etes#REQ_FIRST
c'était écris là.

Mais cela change rien au soucis ma requête il me ressort toujours l'erreur que la colonne n'existe pas.
__________________
"Le pointeur Malkavien..ouiiiiii...c'est moiiiii"
Suryavarman est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/02/2008, 23h34   #13
Membre régulier
 
Avatar de Suryavarman
 
Inscription : mai 2006
Messages : 159
Détails du profil
Informations personnelles :
Âge : 28

Informations forums :
Inscription : mai 2006
Messages : 159
Points : 99
Points : 99
Si je met la requête de la fac pour lister les tables existantes ça fonctionne
, mais dès que je rajoute dans le where
Code :
AND RDB$RELATION_NAME = "LeNomDeMaTable"
ça me sort que cette colonne n'appartient à la table.

( au passage je dois vraiment être une merde, mais en suivant rigoureusement la doc , j'arrive même pas à créer une base de donnée avec ISO8859_1, alors soit la doc d'interbase est complément plus valable pour firebird, ou soit *autocensure après reflexion* )
__________________
"Le pointeur Malkavien..ouiiiiii...c'est moiiiii"
Suryavarman est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/02/2008, 15h44   #14
Membre régulier
 
Avatar de Suryavarman
 
Inscription : mai 2006
Messages : 159
Détails du profil
Informations personnelles :
Âge : 28

Informations forums :
Inscription : mai 2006
Messages : 159
Points : 99
Points : 99
Question stupide... Juste au cas où, aucun rapport avec le fait que je sois sous Vista ( 64bits )?
__________________
"Le pointeur Malkavien..ouiiiiii...c'est moiiiii"
Suryavarman est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/02/2008, 16h07   #15
Expert Confirmé

 
Homme Philippe Makowski
Consultant spécialité Firebird
Inscription : mai 2002
Messages : 2 215
Détails du profil
Informations personnelles :
Nom : Homme Philippe Makowski
Âge : 49
Localisation : France

Informations professionnelles :
Activité : Consultant spécialité Firebird
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 2 215
Points : 3 318
Points : 3 318
aucun rapport avec Vista, juste toi qui lis mal ou écrit mal
tu as tout ce qu'il faut pour bien faire
__________________
Philippe Makowski
IBPhoenix - Firebird
Membre de l'April
makowski est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/02/2008, 18h43   #16
Membre régulier
 
Avatar de Suryavarman
 
Inscription : mai 2006
Messages : 159
Détails du profil
Informations personnelles :
Âge : 28

Informations forums :
Inscription : mai 2006
Messages : 159
Points : 99
Points : 99
Yep ça doit être un truc tout con que j'ai mal fait ou pas fait. Je vais chercher et trouver.

Mici Makowski.
__________________
"Le pointeur Malkavien..ouiiiiii...c'est moiiiii"
Suryavarman est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/02/2008, 21h32   #17
Membre régulier
 
Avatar de Suryavarman
 
Inscription : mai 2006
Messages : 159
Détails du profil
Informations personnelles :
Âge : 28

Informations forums :
Inscription : mai 2006
Messages : 159
Points : 99
Points : 99
Extrait de Ibase.h :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
typedef struct
{
        ISC_SHORT       version;
        ISC_SCHAR       sqldaid[8];
        ISC_LONG        sqldabc;
        ISC_SHORT       sqln;
        ISC_SHORT       sqld;
        XSQLVAR       sqlvar[1] ; 
} XSQLDA;
 
#define XSQLDA_LENGTH(n)        (sizeof (XSQLDA) + (n - 1) * sizeof (XSQLVAR))
 
//et voici comment burland l'utilise dans ses exemples :
 
sqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(3));
....
 
printf("\nColumn name:    %s\n", sqlda->sqlvar[i].sqlname);
printf("Column type:    %d\n", sqlda->sqlvar[i].sqltype);
printf("Column length:  %d\n", sqlda->sqlvar[i].sqllen);
du cou j'ai changé le .h
en mettant leur façon de procéder et de l'utiliser est imbuvable parfaitement horrible :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
    double              budget;
    double              tot_budget;
....
    osqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(1));
    osqlda->sqln = 1;
    osqlda->sqld = 1;
    osqlda->version = 1;
...
    osqlda->sqlvar[0].sqldata = (char *) &tot_budget;
    osqlda->sqlvar[0].sqltype = SQL_DOUBLE + 1;
    osqlda->sqlvar[0].sqllen  = sizeof(budget);
    osqlda->sqlvar[0].sqlind  = &flag3;
Je veux pas être méchant mais firebird est basé sur de la "merde".

Autre exemple : pour récupérer une requête il faut envoyer un XSQLDA bateau, récupérer le nombre de XSQLVAR , puis préparer un autre XSQLDA à la bonne taille pour la remplir à nouveau. Leurs fonctions ne sont pas foutu d'allouer une structure adaptée à la taille du résultat de la requête.

Enfin voila je suis pas nul, je suis capable de bosser dans un projet de 200k lignes pourries et comprendre comment ça fonctionne. Là ça fait une semaine que j'essaie de créer une table en vérifiant si elle existe pas déjà à l'aide d'une requête. C'est un concept simple pourtant. Là je viens de me décider à prendre la requête de la faq, même si je la comprend pas il est dit qu'elle renvoi les noms des tables contenu dans la bd, j'ai donc décidé de traité le résultat dans un boucle.
Le sqlda est alloué puis envoyer à isc_dsql_describe pour le remplir, mais en sorti j'ai un sqlda complètement pourri.

Je vais prendre une pause, peut être réessayer car je déteste abandonner pour une raison d'incompréhension. Mais franchement quand je vois linq de windows et cette chose de burland... enfin maintenant je vais sauvegarder toutes mes données dans un fichier xml et les requêtes je les substituerais avec mon framework.
__________________
"Le pointeur Malkavien..ouiiiiii...c'est moiiiii"
Suryavarman est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/03/2008, 12h30   #18
Expert Confirmé

 
Homme Philippe Makowski
Consultant spécialité Firebird
Inscription : mai 2002
Messages : 2 215
Détails du profil
Informations personnelles :
Nom : Homme Philippe Makowski
Âge : 49
Localisation : France

Informations professionnelles :
Activité : Consultant spécialité Firebird
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 2 215
Points : 3 318
Points : 3 318
1/ si tu veux causer de l'API, c'est dans la liste architect
2/ ibpp est là pour t'aider et te simplifier le boulot
3/ ton problème n'est pas l'API mais ta requete
si tu veux savoir si la table ou vue TOTO existe tu fais :
Code :
SELECT RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$RELATION_NAME='TOTO'
ou
Code :
SELECT COUNT(*) FROM RDB$RELATIONS WHERE RDB$RELATION_NAME='TOTO'
__________________
Philippe Makowski
IBPhoenix - Firebird
Membre de l'April
makowski est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/03/2008, 15h38   #19
Membre régulier
 
Avatar de Suryavarman
 
Inscription : mai 2006
Messages : 159
Détails du profil
Informations personnelles :
Âge : 28

Informations forums :
Inscription : mai 2006
Messages : 159
Points : 99
Points : 99
Merci beaucoup makowski. J'arrête pour un moment Firebird, je dois avancé, je suis parti sur du XML pour sauvegarder mes données. Quand viendra l'heure de gérer par des requêtes un grand volume de donnée, je retenterais Firebird, surement avec ibpp.

Merci encore pour ton aide.
__________________
"Le pointeur Malkavien..ouiiiiii...c'est moiiiii"
Suryavarman est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/03/2008, 10h48   #20
Membre Expert
 
Avatar de Barbibulle
 
Frédéric
Inscription : octobre 2002
Messages : 1 722
Détails du profil
Informations personnelles :
Nom : Frédéric
Âge : 42

Informations forums :
Inscription : octobre 2002
Messages : 1 722
Points : 2 025
Points : 2 025
C'est vrai qu'utiliser l'API, alors qu'il existe des moyens plus simple d'accèder à firebird, c'est un peu réinventer la roue...

De plus je vous conseille d'éviter de cumuler les difficultées. Vous ne connaissez pas ou mal le SQL et l'API de firebird. Afronter tout d'un coup quand ca ne fonctionne pas n'est pas évident

Commencez par installer un outil d'administration de firebird et testez vos requetes avec. Celà vous évitera déjà de chercher si l'erreur vient de votre programme ou du SQL.

Bon courrage
Barbibulle est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 03h37.


 
 
 
 
Partenaires

Hébergement Web