Bonjour,
Je commence en base de données et je voudrai savoir si quelqu'un connait un moyen d'utiliser wchar_t avec pro c. Merci de vos réponses.
Version imprimable
Bonjour,
Je commence en base de données et je voudrai savoir si quelqu'un connait un moyen d'utiliser wchar_t avec pro c. Merci de vos réponses.
Oracle supporte les chaines Unicode de type UTF-16/UCS-16 (taille fixe sur 2 bytes).
Le type C utilisé par Oracle est "utext".
Sous Windows, wchar_t est implémenté sur 2 bytes. Donc il y a une correspondance implicite entre wchar_t et le type oracle utext.
Sous Linux et autres unixes, wchar_t est souvent implémenté sur 4 bytes. Dans ce cas, wchar_t est incompatible avec utext.
Pro*C ne supporte les chaines unicode que pour les variables utilisateur utilisées pour les binds dans les requêtes.
Les ordres SQL sont eux uniquement supporté en ANSI (char*) .
Enfin, il faut aussiinclure le header "sqlucs2.h" pour gérer les chaines unicode en pro*c
Exemple tiré des docs PRO*C :
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 #include <sqlca.h> #include <sqlucs2.h> main() { utext employee1[20] ; /* Change to STRING datatype: */ EXEC ORACLE OPTION (CHAR_MAP=STRING) ; utext employee2[20] ; EXEC SQL CREATE TABLE emp (ename CHAR(60)) ; ... /*********************************************************** Initializing employee1 or employee2 is compiler-dependent. **********************************************************/ EXEC SQL INSERT INTO emp (ename) VALUES (:employee1) ; ... EXEC SQL SELECT ename INTO :employee2 FROM emp; /* employee2 is now not blank-padded and is null-terminated */ ...
ca veut dire que si je lis un fichier unicode il doit etre utf-16? comment est ce qu'on arrive a intégrer dans Oracle un fichier unicode sous unix?
Sous unix, si ton flux externe est récupéré sous forme de wchar_t, il te faudra le convertir en UTF-16 pour l'intégrer dans Oracle
donc intégrer un fichier encodé UTF-8 dans une base Oracle ne se passe pas bien sous Linux?
UTF8, c'est particuliers car cela peut être géré comme des char *.
Il faut faire juste attention à la longueur des chaines. Une colonne VARCHAR2(30) c'est 30 bytes et pas 30 caractères. Alors qu'une colonne VARCHAR2(30 CHAR) c'est caractères qui peut être 90 bytes.
En gros voici ce que je dois faire:
lire un fichier avec des caractères spéciaux (UTF-8) remplir en C des structures
intégrer dans la base ces structures
Pourrais tu me dire quels types de données sont susceptibles de fonctionner
Bonjour,
Y'a t-il un moyen de convertir des données wchar_t (4 bytes sur Linux) en UTF16 pour une intégration dans une base oracle (type utilisé uvarchar)? Merci pour vos réponses
Bonjour,
Le but est donc de convertir une chaine de unsigned long (wchar_t sous linux - fixed 4 bytes based UTF32) en unsigned short (fixed 2 bytes UTF16).
Il s'agit donc d'une "compression" de 4 bytes vers 2 bytes avec une éventuelle conversion des codepoints qui prennent 4 bytes (ce qui est très rare actuellement) vers 2 bytes (dans ce cas, il faut utiliser un codepoint par défaut sur 2 bytes ).
J'ai du implémenter ces conversions dans OCILIB et j'ai adapté les fonctions C dispos sur le site du consortium d'unicode.
Voici la fonction que j'utilise dans OCILIB (modifiée - j'ai enlevé mes macros spécifiques)
PS : La mise en forme automatique du code est basée sur SQL et non pas C
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79 /* unicode constants */ #define UNI_SHIFT (int) 10 #define UNI_BASE (unsigned long) 0x0010000UL #define UNI_MASK (unsigned long) 0x3FFUL #define UNI_REPLACEMENT_CHAR (unsigned long) 0x0000FFFD #define UNI_MAX_BMP (unsigned long) 0x0000FFFF #define UNI_MAX_UTF16 (unsigned long) 0x0010FFFF #define UNI_MAX_UTF32 (unsigned long) 0x7FFFFFFF #define UNI_MAX_LEGAL_UTF32 (unsigned long) 0x0010FFFF #define UNI_SUR_HIGH_START (unsigned long) 0xD800 #define UNI_SUR_HIGH_END (unsigned long) 0xDBFF #define UNI_SUR_LOW_START (unsigned long) 0xDC00 #define UNI_SUR_LOW_END (unsigned long) 0xDFFF /* ------------------------------------------------------------------------ * * OCI_StringCopy4to2bytes * ------------------------------------------------------------------------ */ long OCI_StringCopy4to2bytes(const unsigned long* src, long src_size, unsigned short* dst, long dst_size) { long cp_size = 0; const unsigned long* src_end; const unsigned short* dst_end; if (src == NULL || dst == NULL) return 0; src_end = src + src_size; dst_end = dst + dst_size; while (src < src_end) { unsigned long c; if (dst && dst >= dst_end) return -1; c = *src++; if (c <= UNI_MAX_BMP) { if (c >= UNI_SUR_HIGH_START && c < UNI_SUR_LOW_END) { if (dst) *dst++ = UNI_REPLACEMENT_CHAR; } else if (dst) *dst++ = (unsigned short) c; cp_size++; } else if (c > UNI_MAX_LEGAL_UTF32) { if (dst) *dst++ = UNI_REPLACEMENT_CHAR; cp_size++; } else { if (dst && (dst + 1) >= dst_end) return -2; c -= UNI_BASE; if (dst) { *dst++ = (unsigned short)((c >> UNI_SHIFT) + UNI_SUR_HIGH_START); *dst++ = (unsigned short)((c & UNI_MASK ) + UNI_SUR_LOW_START ); } cp_size++; cp_size++; } } return cp_size; }
Merci je vais tester.