|
-
III-1 Introduction à SQL *
-
III-1-1 Requêtes de gestion de transaction *
-
III-1-2 Principes de SQL *
-
III-1-3 Les différents help sous SQL *
-
III-1-4 Noms des objets *
-
III-1-4-1 Conventions sur les noms des objets *
-
III-1-4-2 Identificateurs délimités *
-
III-1-5 Création de schéma *
-
III-1-6 Synonymes *
-
III-1-6-1 création d'un synonyme *
-
III-1-6-2 destruction d'un synonyme *
-
III-1-7 Types de données *
-
III-1-8 Les constantes utilisées dans SQL *
-
III-1-9 Principaux ordres SQL *
-
III-1-9-1 ordres SQL de manipulation de données *
-
III-1-9-2 ordres SQL d'administration de base *
-
III-2 Select, premiers pas *
-
III-2-1 L'ordre select *
-
III-2-2 Opérateurs de comparaison *
-
III-2-3 Opérateurs logiques *
-
III-2-4 Enlever les doubles *
-
III-2-5 Faire des recherches triées *
-
III-2-6 Mettre un commentaire dans une requête *
-
III-2-7 Recherches sur chaînes de caractères *
-
III-2-7-1 comparaison d'une colonne textuelle à une constante
*
-
III-2-7-2 comparaison d'une colonne textuelle à un modèle,
uniquement avec le comparateur like *
-
III-2-7-3 séquences spéciales *
-
III-3 Fonctions *
-
III-3-1 Fonctions de conversion de type *
-
III-3-2 Fonctions sur les dates *
-
III-3-3 Fonctions numériques *
-
III-3-4 Fonctions sur chaînes de caractères *
-
III-3-5 La fonction ifnull *
-
III-4 Conditions de recherche du where *
-
III-4-1 Définition d'une expression *
-
III-4-2 Définition d'une condition de recherche *
-
III-4-3 Utilisation de "between" *
-
III-4-4 Utilisation d'une "subquery" avec "in" : *
-
III-4-5 Utilisation d'une "subquery" avec "exists"
*
-
III-4-6 Utilisation de "any et all" *
-
III-4-7 Utilisation de "is null" *
-
III-5 Jointure de tables *
-
III-5-1 Jointure interne *
-
III-5-2 Jointures externes *
-
III-6 Agrégations *
-
III-6-1 Les fonctions d'agrégation *
-
III-6-2 Agrégats avec clauses where, group by et having *
-
III-6-3 Ordre conceptuel dans lequel les opérations sont effectuées
*
-
III-7 Définitions à propos de select, subselect, et subquery
*
-
III-8 Création de table *
-
III-8-1 Syntaxe de l'ordre create table *
-
III-8-2 Valeurs nulles et par défaut des colonnes *
-
III-8-3 Contraintes sur les colonnes *
-
III-8-4 Contraintes sur les tables *
-
III-8-5 Clause with du create table *
-
III-8-6 Limitations *
-
III-9 Création de table à partir d'une recherche *
-
III-9-1 Syntaxe de create table *
-
III-9-2 Options supplémentaires de la clause with *
-
III-10 Création de tables temporaires *
-
III-11 Création de vue *
-
III-12 Destruction d'une table ou d'une vue *
-
III-13 Mise à jour de table *
-
III-13-1 Ajout de lignes dans une table *
-
III-13-2 Destruction de lignes d'une table *
-
III-13-3 Mise à jour de lignes d'une table *
-
III-14 Commentaires sur les tables et les colonnes *
-
III-15 Chargement et déchargement de tables (export/import)
*
-
III-16 Sécurité des données*
-
III-16-1 Privilèges dans l'environnement OpenIngres *
-
III-16-2 Privilèges objets *
-
III-16-2-1 l'ordre grant *
-
III-16-2-2 suppression de privilèges *
-
III-16-2-3 privilèges dépendants *
-
III-16-2-4 vues et privilèges *
-
III-16-2-5 procédures de bases de données et privilèges
*
-
III-16-2-6 privilège de mise à jour multicolonne *
-
III-16-3 Privilèges utilisateurs *
-
III-16-3-1 présentation *
-
III-16-3-2 opérations et syntaxe *
-
III-16-3-3 gestion des locations *
-
III-16-4 Contrôle d'accès par les vues *
-
III-16-5 Privilèges sur une base et sur l'installation *
-
III-16-5-1 généralités *
-
III-16-5-2 privilèges sur une base et l'installation complète
*
-
III-16-5-3 exemples *
-
III-17 Les contraintes d'intégrité *
-
III-17-1 Créer une contrainte d'intégrité *
-
III-17-2 Lister les contraintes d'intégrité *
-
III-17-3 Détruire les intégrités en indiquant leurs
numéros *
-
III-18 Gestions d'événements, règles et procédures
*
-
III-18-1 Introduction *
-
III-18-2 Gestion des procédures *
-
III-18-3 Gestion des règles *
-
III-18-4 Exemples de règles et procédures *
-
III-19 Autres types de données : les objets spatiaux *
-
III-19-1 Le type point "point" *
-
III-19-2 Le type boîte "box" *
-
III-19-3 Le type segment "lseg" *
-
III-19-4 Le type ligne "line" *
-
III-19-5 Le type ligne longue "long line" *
-
III-19-6 Le type polygone "polygon" *
-
III-19-7 Le type polygone long "long polygon" *
-
III-19-8 Le type cercle "circle" *
-
III-19-9 Tableau des formats des types spatiaux *
-
III-19-10 Les opérateurs spatiaux disponibles *
-
III-19-11 Les fonctions disponibles sur les attributs de types spatiaux
*
III-1 Introduction
à SQL
III-1-1 Requêtes
de gestion de transaction
Chaque entrée dans sql (isql) débute une
transaction;
chaque sortie de sql (isql) termine une transaction.
Mises à jour et insertions ne sont sauvegardées qu'en
fin de transaction, même si les données paraissent modifiées
en cours de transaction.
roolback; commit; |
valide les modifications apportées
depuis le début de transaction, démarre une nouvelle transaction |
set autocommit on | off; |
placé à on,
chaque requête de modification dans la base est automatiquement validée.
Sur les machines du CIR, par défaut à on lorsqu'on
appelle isql ou sql, à off si on appelle ingmenu |
III-1-2 Principes
de SQL
SQL est un langage, normalisé par l?ANSI, permettant tant la définition
que la manipulation et le contrôle d?une base de données relationnelle.
Il sert à l?administrateur de la base (pour la gérer) comme
à l?utilisateur final (pour l?interroger).
C?est un langage interactif (outil isql) ; il est également
utilisé comme langage intégré ("embedded ")
dans un langage de programmation (Fortran ou C) pour le développement
d?applications.
Ce langage possède ses objets, sa syntaxe, ses commandes, ses
mots-clés.
La commande help fournit des informations sur les objets de la
base de données.
III-1-3 Les différents
help sous SQL
help; |
donne le nom des objets accessibles de la base,
leur propriétaire et leur type (table ou vue) |
help * ; |
mêmes informations que help, plus noms
et types des colonnes |
help nom_objet; |
propriétaire, colonnes de l?objet (table,
vue, index) nom_objet |
help table nom_table; |
informations complètes sur l'organisation,
la place occupée, le nombre de lignes, les colonnes et leur type |
help index n_index; |
informations complètes sur l'index n_index |
help view vue; |
définition de la vue indiquée |
help comment table nom_table; |
donne le commentaire attaché à
la table nom_table |
help comment column nom_table
nom_col; |
donne le commentaire attaché à
la colonne nom_col de la table nom_table |
help permit on | integrity nom_table; |
informations sur les droits associés
à la table ou la vue, les contraintes d?intégrité |
help constraint nom_table |
affiche les contraintes définies sur
les colonnes de la table nom_table. Ces contraintes ne sont pas les mêmes
que les intégrités affichées par help integrity |
help default nom_table |
affiche les valeurs par défaut définies
sur les colonnes de la table |
help procedure proc; |
informations sur la procédure proc |
help rule nom_regle; |
informations sur la règle nom_regle |
help synonym nom_syn |
information sur le synonyme nom_syn. |
help synonym *. |
Pour afficher tous vos synonymes |
help synonym *.* |
Pour afficher tous les synonymes qui vous sont
accessibles |
help help; |
imprime cette liste : les 'objets' SQL (tables,
vues, etc.) pour lesquels il y a un help |
help sql ; |
donne la liste des commandes SQL pour lesquelles
il existe un Help |
help sql req_sql; |
informations sur l'ordre req_sqlen question |
III-1-4 Noms des
objets
III-1-4-1 Conventions sur les noms
des objets
Les règles pour nommer les objets d'une base (tables, colonnes,
vues, procédures) sont les suivantes :
-
les noms ne peuvent contenir que des caractères alphanumériques
et doivent commencer par une lettre ou (sauf les noms de bases) par un
"blanc souligné";
-
il n'y a pas de distinction minuscules/majuscules, par défaut (voir
le réglage de db_name_case);
-
les noms peuvent contenir les caractères suivants : chiffres de
0 à 9, #, @ et $; les noms utilisés comme identificateurs,
entre guillemets peuvent contenir d'autres caractères spéciaux;
-
les noms de tables ne peuvent pas commencer par "ii" (réservé
aux tables systèmes);
-
la longueur maximale d'un nom est de 32 caractères (24 dans l'ancienne
version de Ingres)
Les noms des objets peuvent être donnés en utilisant des identificateurs
"réguliers" (sans guillemets) ou "délimités" (entourés
par des guillemets).
III-1-4-2 Identificateurs délimités
:
Ils permettent l'utilisation de mots-clés dans les noms d'objets.
Ils permettent l'utilisation de caractères spéciaux dans
les noms :
blanc, étoile (*), tiret (-), etc.,
-
les noms doivent être entre guillemets
-
les noms peuvent être utilisés pour les noms de : tables,
vues, identificateurs de privilèges, database events, etc.
Exemple de nom de table donné par un identificateur régulier
:
select * from employees
Exemple de nom de table donné par un identificateur délimité
:
select * from "ma table"
Vous ne pouvez pas introduire les caractères suivants dans des noms
d'objets, en utilisant les identificateurs délimités ou réguliers
:
\ |
^ |
{ } |
DEL (ASCII 127 ou X'7F') |
! |
' (ASCII 96 or X'60') |
~ |
|
Pour utiliser des guillemets dans un identificateur délimité,
il faut les répéter, par exemple : """nom""identificateur"""
est interprété comme :
"nom"identificateur"
Les blancs de fin sont supprimés des noms utilisant les identificateurs
délimités. Par exemple, la requête :
create table "essai blancs " (scolumn int);
crée une table appelée "essai blancs";
si la chaîne ne contient que des blancs, le nom consistera en
un seul blanc.
III-1-5 Création
de schéma
Un schéma, qui correspond logiquement à une base à
l'intérieur d'une base, regroupe les différents objets (tables,
vues, privilèges) qui appartiennent à un utilisateur.
Le nom du schéma est celui de l'utilisateur qui l'a créé.
Chaque utilisateur ne peut créer qu'un seul schéma par base.
Il n'y aura donc pas création de schéma s'il en existe déjà
un pour l'utilisateur.
La création d'un schéma se fait soit par une instruction
spécifique, soit, si un utilisateur n'a pas de schéma, automatiquement
lors de la création de la première table par l'utilisateur
Syntaxe : .
create schema authorization nom_schéma
[creation_objet {creation_objet}];
creation_objet peut être un create table, create view
ou grant.
Exemple :
create schema authorization mon_nom_user
create table foyer85
(ident integer, an i1, depcom integer,
cprof i1, nbvoi i1)
III-1-6 Synonymes
III-1-6-1 création d'un synonyme
On peut créer des synonymes (qui sont des alias) pour les tables,
les vues ou les index.
create synonym nom_syn for
[schema.]nom_objet;
Ces synonymes peuvent être employés à la place des
noms réels (ceux indiqués dans une instruction create)
dans tout ordre SQL : le remplacement par les noms d'objet réels
se fait au moment de l'exécution.
Exemple
create synonym "table foyer"
on
foyer
Nom |
Propriétaire |
Type |
foyer |
mon_nom_user |
table |
"table foyer" |
mon_nom_user |
synonym |
III-1-6-2 destruction d'un synonyme
drop synonym nom_syn
Exemple
drop synonym "table foyer"
III-1-7 Types de données
liste des types possibles
Classe |
Catégorie |
Type de données |
Usage et valeurs
limites |
Caractères |
longueur fixe |
c |
|
|
|
char (character) |
char(i)
0<i<2001 |
|
Varying length |
text |
|
|
|
varchar |
varchar(i)
0<i<2001 |
|
|
long varchar |
long varchar(i)
0<i<2goctets |
Numérique |
numérique exact |
integer
(integer4) |
entier sur 4 octets,
de -2,1*10**9 à +2,1*10**9 |
|
|
smallint
(integer2) |
entier sur 2 octets,
de -32768 à 32767 |
|
|
integer1 |
entier sur un octet,
de -127 à 128 |
|
|
decimal |
decimal (p, s)
p : précision (nombre total de chiffres), 1 <=p<=
31
s : scale, échelle, nombre de chiffres après
la virgule |
|
numérique approché |
float (n) |
float (n)
où n = précision
0 <=n<= 52
0< n <=7 équivaut à real, float4 stockage
sur 4 octets
8<= n <=52 équivaut à float, float8,
double precision
stockage sur 8 octets |
|
|
float (float8,
double precision) |
flottant sur 8 octets,
10**38 max. (17 déc.) |
|
|
float4 (real) |
flottant sur 4 octets,
10**38 max. (7 déc.) |
Abstrait |
|
date |
donne date ou date+heure,
12 octets stockés, 25 à l'affichage |
|
|
money |
monnaie, avec un F
à gauche, 8 octets |
|
clé logique |
table_key |
table_key [not
| with system_maintained]
la valeur de la colonne est une clé logique unique
dans la table, et peut être automatiquement maintenue par Ingres
(with system_maintained) |
|
|
object_key |
object_key [not
| with system_maintained]
la valeur de la colonne est une clé logique unique
dans la base, et peut être automatiquement maintenue par Ingres (with
system_maintained) |
Binaire |
|
byte |
byte (n)
données
binaires de longueur fixe
n<= 2000 |
|
|
byte varying |
byte varying (n)
données
binaires de longueur variable |
|
|
long byte |
long byte (n)
données
binaires
n<= 2 gigaoctets |
III-1-8 Les constantes
utilisées dans SQL
Vous pouvez utiliser les constantes suivantes dans les requêtes SQL
:
Constante |
Signification |
now |
date et heures courantes. Cette constante doit
être donnée entre apostrophes. |
null |
Indique une valeur manquante ou inconnue dans
une table. |
today |
date du jour. Cette constante doit être
donnée entre apostrophes. |
>user |
identificateur de l'usager de la session Ingres
(pas l'usager Unix) |
current_user |
comme user. |
system_user |
identificateur de l'usager Unix qui a démarré
la session Ingres |
initial_user |
identificateur de l'usager Ingres au début
de la session |
session_user |
comme user. |
Ces constantes peuvent être utilisées dans les requêtes
et expressions, par exemple :
select date('now');
insert into commandes
(numero, agent, date_facture)
values ('123', user, date('today')+date('7
days'));
Pour préciser l'usager effectif au début de la session, utilisez
le flag -unom des commandes (isql, sql, ...) ou la clause "identified
by" de l'instruction "sql connect".
III-1-9 Principaux ordres
SQL
III-1-9-1 ordres SQL de manipulation
de données
select |
toutes recherches |
update |
mise à jour (corrections) |
insert |
ajout de lignes |
delete |
destruction de lignes |
III-1-9-2 ordres SQL d'administration
de base
create schema |
création de schéma |
copy table |
chargement/déchargement. de tabledans
un fichier |
create table |
création de table |
alter table |
modification de contraintes sur une table |
create view |
création de vue logique |
modify |
change l'organisation physique des données,
pour accélérer les recherches |
create index |
création d'un index |
grant |
autorisation d'accès aux données
d'un objet (table, vue, procédure) |
create integrity |
définit des contraintes d'intégrité
sur une table |
drop |
détruit un objet (table, vue, accès,
index) |
create synonym |
création de synonymes |
III-2 Select, premiers
pas
III-2-1 L'ordre select
Le résultat d'un select est équivalent à une table.
Syntaxe :
select col1 {,coli} from tab1
{,tabi} [ where cond1 {opl condi}];
où : coli est un nom de
colonne, tabi un nom de table, condi une condition de recherche;
exemple :
select tranche from commune
where
depcom
=
93063
;
select
ident, nbpers from foyer
where cprof = 44 and
cnaiss >= 45 ;
select * from vehicule where
kman > 20000 ;
III-2-2 Opérateurs
de comparaison
> <
>= <=
= != ou <>
like
Les opérateurs de comparaison peuvent être utilisés
avec des colonnes de type numérique ou caractère, à
l?exception de like qui ne s'utilise qu'avec des colonnes de type
caractère.
Conditions des comparaisons avec un type decimal :
type1 |
type2 |
|
decimal |
decimal |
pas de conversion |
decimal |
float |
decimal converti en float |
decimal |
integer |
integer converti en decimal |
III-2-3 Opérateurs
logiques
not and or
Attention à leurs priorités quand ils sont combinés
: il faut mettre des parenthèses.
III-2-4 Enlever les doubles
select distinct
exemple :
select distinct tranche from
commune;
III-2-5 Faire des recherches
triées
select distinct dept from
commune order by dept [asc|desc];
-
le tri peut s'effectuer sur plusieurs colonnes
-
les colonnes triées doivent être présentes dans la
clause select
-
le tri est ascendant par défaut (asc)
récapitulatif de la syntaxe du select étudié
jusqu'ici
select [distinct] expr [ as
libelle]
{, expr [ as libelle]}
from table
[where condition_recherche {or |
and [not] condition_recherche}];
III-2-6 Mettre un commentaire
dans une requête
exemple :
/* ...commentaire...*/
select * from commune
where dept = 77
/* and psdc > 500 */ and
tranche = 3 g
III-2-7 Recherches
sur chaînes de caractères
III-2-7-1 comparaison d'une colonne
textuelle à une constante
expression compar constante
compar étant : < > = <= >= !=
la constante s'écrit entre cotes ex : nom = 'Dupont'
III-2-7-2 comparaison d'une colonne
textuelle à un modèle, uniquement avec le comparateur like
nom_col [not] like modèle
Dans un modèle, on peut utiliser des caractères spéciaux
:
% n'importe quelle chaîne de caractères, y compris
la chaîne vide
_ n'importe quel caractère
ex : '%ton' reconnaîtra 'Tonton', 'mironton', 'ton'
ex : '___ton' reconnaîtra 'Tonton', 'chaton'
III-2-7-3 séquences spéciales
\[aB3\] reconnaîtra un caractère parmi a, B
ou 3
\[1-x\] reconnaîtra un caractère pris entre
1 et x dans l'ordre des caractères ASCII (de 1 à x dans notre
cas)
Attention : pour ces séquences spéciales entourées
de crochets, il faut obligatoirement indiquer quel est le caractère
d'échappement. Dans l?exemple qui suit c?est le contre-slash. Sinon,
SQL comparerait à la chaîne ?\[A-D\]?.
ex :
nom like '\[A-D\]%' escape
\
(tous les noms commençant par A,B,C,D)
Les fonctions s'appliquent aux constantes, colonnes, expressions; elles
peuvent s'imbriquer en respectant le type de leurs arguments.
III-3 Fonctions
III-3-1 Fonctions de
conversion de type
char (qque) |
type quelconque en char |
varchar (qque) |
type quelconque en varchar |
date (ch) |
toute chaîne en date |
float4 (^dat) |
tout sauf date en float4 ; idem float8 |
int1 (^dat) |
tout sauf date en integer1 ; idem int2
et
int4 |
decimal ( expression
[,précision [,scale] ] ) |
tronque la partie décimale si besoin;
peut générer une erreur de débordement si le nombre
est trop grand. |
Valeurs de p et s pour les conversions par la fonction decimal,
selon le type converti :
type converti |
p
|
s
|
money |
15
|
2
|
float |
15
|
0
|
integer4 |
11
|
0
|
smallint/integer1 |
5
|
0
|
III-3-2 Fonctions sur
les dates
d1 + | - id2 |
ajouter/retrancher un intervalle de date à
une date |
dow (date) |
jour de semaine de date en anglais ('Mon', 'Tue') |
date_trunc (unité, date) |
date tronquée à l?unité
indiquée |
date_part (unité, date) |
entier, valeur de l'unité indiquée |
interval (unité, interv) |
convertit un intervalle de date en valeur décimale
de l'unité indiquée |
Les unités mentionnées ci-dessus doivent être obligatoirement
indiquées entre cotes.
exemple :
select distinct date_part(?year?,
datachat) from vehicule ;
donne les différentes valeurs de l?année d?achat du véhicule
liste des unités et synonymes admis :
second |
seconds |
sec |
secs |
|
minute |
minutes |
min |
mins |
|
hour |
hours |
hr |
hrs |
|
day |
days |
|
|
|
week |
weeks |
wk |
wks |
|
month |
months |
mo |
mos |
|
quarter |
quarters |
qtr |
qtrs |
(trimestre) |
year |
|
years |
yr |
yrs |
constantes connues de Ingres :
'now'
'today'
exemples de dates :
'02/28/85'
'28-feb-85',
'02/28/85 10:30:25'
'02/28/85' + '1 yr 2 mo 3 day'
Pour pouvoir utiliser les dates, en indiquant jour, mois, an ainsi : 'jj/mm/aa',
il faut positionner, au niveau Unix, la variable II_DATE_FORMAT par la
commande :
$ setenv II_DATE_FORMAT MULTINATIONAL
;
III-3-3 Fonctions numériques
Opérations sur les colonnes et constantes numériques
:
** * / + -
pas de restriction théorique à leur combinaison;
attention aux priorités, mettre des parenthèses
fonctions
abs (x)
atan (x)
cos (x)
exp (x)
log (x)
mod (i, j) i, j et le résultat de mod sont des entiers
sin (x)
sqrt (x)
remarques sur le type "decimal" :
Les opérateurs et fonctions arithmétiques peuvent être
utilisés avec des types "decimal" :
-
les opérations arithmétiques peuvent se faire sur des valeurs
de précision et échelle différentes;
-
les fonctions ensemblistes (max, min, avg, sum)
prennent des arguments de type decimal;
-
la fonction avg rend un résultat plus précis qu'avec
des types float;
-
la fonction mod tronque les arguments à leur partie entière
et rend un entier;
-
toutes les autres fonctions numériques convertissent les valeurs
en float et retournent un float.
III-3-4 Fonctions sur
chaînes de caractères
charextract (c1,n) |
le n-ième caractère de c1 |
concat (c1,c2) |
concaténation |
c1 + c2 |
concaténation |
left (c1,l1) |
les l1 premiers caractères de c1 |
right (c1,l1) |
les l1 derniers caractères de c1 |
size (c1) |
taille déclarée de c1 |
length (c1) |
longueur de la chaîne sans les blancs
à droite |
locate (c1,c2) |
1ère occurrence de c2 dans c1 |
lowercase (c1) |
c1 en minuscules |
uppercase (c1) |
c1 en majuscules |
pad (c1) |
c1 et ses blancs de fin |
trim (c1) |
c1 sans blancs de fin |
squeeze (c1) |
compresse les caractères d?espacement |
shift (c1,ndep) |
déplacement vers la droite ou la gauche |
Remarque :
Le type de donnée n?est pas changé par ces fonctions
: ainsi, si adresse est un char(150), la fonction left (adresse,3) rendra
un char(150).
III-3-5 La fonction ifnull
elle permet d'attribuer une valeur à une colonne prenant la valeur
null
ifnull (v1, v2) a pour valeur v1 si v1 est non "null" et pour
valeur v2 si v1 est "null"
Par exemple, les fonctions d'agrégations sum, avg,
max
et min rendent une valeur nulle si l'ensemble sur lequel elles portent
est vide. Pour recevoir une valeur non nulle, vous pouvez utiliser la fonction
ifnull
comme ceci :
ifnull(sum(employee.salaire)/25,
-1)
Si la somme de employee.salaire est nulle, on aura -1.
III-4 Conditions
de recherche du where
III-4-1 Définition
d'une expression
Qu'est-ce qu'une expression ? c'est une combinaison d'opérateurs
et d'opérandes qui donnent une valeur ou un ensemble de valeurs
:
constante
colonne
expression oper_arith expression
fonction(expression)
exemples :
date_part ('year', datachat) =
1900
+ ancstr
left (char (depcom), 2)
III-4-2 Définition
d'une condition de recherche
Une condition de recherche est une collection de prédicats,
éventuellement combinés par les opérateurs booléens
or,and,
not
,
avec éventuellement un parenthésage pour indiquer l?ordre
d?évaluation.
III-4-3 Utilisation de
"between"
exp between exp1 and exp2
exemple: sélection des véhicules dont le rapport masse/puissance
fiscale est compris entre 2 et 8
select * from vehicule where
masse / puisfisc between 2 and
8
;
III-4-4 Utilisation
d'une "subquery" avec "in" :
exp in (exp1, exp2, ... , expi);
ou
exp in ( select...)
exemple : sélection des véhicules dont la puissance fiscale
est une valeur de la liste 2, 7, 11
select * from vehicule where
puisfisc in (2, 7, 11);
exemple : sélection des identificateurs de foyers qui habitent des
communes de plus de 10000 habitants
select distinct ident from
foyer where depcom in
(select depcom from commune
where psdc > 10000);
III-4-5 Utilisation
d'une "subquery" avec "exists"
le prédicat est vrai si la subquery retourne un ensemble de valeurs
non vide :
[not] exists (select...)
exemple : sélection des identificateurs de foyers qui ne possèdent
pas de véhicule
select ident from foyer
where not exists
(select * from vehicule
where vehicule.ident = foyer.ident)
;
III-4-6 Utilisation
de "any et all"
exp comparateurs any | all (select...)
any est équivalent à in
( select ...)
exemple : sélection des foyers qui ont un revenu supérieur
à tous les revenus des csp "44"
select * from foyer
where revenu > all
(select revenu from foyer
where cprof = 44 ) ;
exemple : sélection des identificateurs de foyers qui ont au moins
un véhicule dans la base
select ident from foyer
where ident = any
(select ident from vehicule
)
;
III-4-7 Utilisation
de "is null"
exp is [not] null
exemple : sélection des identificateurs de foyers qui n'ont pas
de variable depcom définie
select ident from foyer
where
depcom is null ;
III-5 Jointure
de tables
III-5-1 Jointure interne
On peut joindre jusqu'à 30 tables.
La définition de la jointure apparaîtra dans la clause
where du select.
Exemple : donner l'identificateur, l'année de naissance, l'année
du panel, et la puissance fiscale de tous les véhicules de tous
les foyers :
select f.ident, f.cnaiss, f.an,
v.puisfisc
from foyer f, vehicule v
where f.ident = v.ident and
f.an = v.an ;
On utilise des synonymes abrégés pour désigner
les tables s?il risque d?y avoir une ambiguïté du fait de l?existence
de la même colonne dans plusieurs tables.
Toutes les tables intervenantes doivent être présentes
dans le from.
On doit spécifier, à l'aide des synonymes, la tabled'appartenance
pour toute colonne commune à deux tables.
La jointure interne donne comme table résultats une table contenant
les lignes communes aux 2 tables d'origine.
Par exemple, si on fait la jointure entre une table de foyers et une
table de véhicules, suivant la condition "tel foyer possède
un véhicule", la jointure interne ne donnera que les foyers ayant
un ou plusieurs véhicules dans la table véhicules.
Exemple de schéma conceptuel :
table foyer
|
|
table vehicule
|
tables de départ
|
ident
A1
|
|
ident
A2
|
tous les "ident" A2 de la table véhicule sont
contenus dans la partie A1 de la table foyer; les "ident" B1 de la table
foyer ne sont pas contenus dans la table véhicule
|
|
|
|
|
B1
|
|
B2
|
|
|
|
|
|
|
|
|
|
table foyer
|
|
table vehicule
|
jointure interne
|
ident
A1+
|
|
ident
A2
|
A1+ représente les tuples de A1 de mêmes
ident que A2,
éventuellement dupliqués pour avoir le même
nombre de lignes dans A1+ et dans A2
|
exemple : sélection des identificateurs, département,
nombre de personnes des foyers ainsi que l'année d'enquête
et la marque-modèle des véhicules associés
select f.ident, f.depcom, f.nbpers,
v.an, v.marqmod
from vehicule v inner join
foyer f
on f.ident = v.ident
équivalent à
select f.ident, f.depcom, f.nbpers,
v.an, v.marqmod
from vehicule v , foyer f
where f.ident = v.ident
III-5-2 Jointures externes
On peut désirer aussi avoir les informations pour les adultes sans
enfants, ou les enfants sans parents, voire les deux cas réunis
: on voudra donc des informations sur des lignes ne vérifiant pas
la condition de jointure et on parlera alors de jointure externe, qui peut
être "à gauche", "à droite", ou "complète".
Dans tous les cas, une table (ou vue) résultant d'une jointure
sera dite interne si seules les lignes vérifiant la condition
de jointure sont produites, et externe si toutes les lignes sont
produites, qu'elles vérifient ou pas la condition de jointure. Les
colonnes provenant de la table interne ne vérifiant pas la condition
de jointure auront la valeur "null".
Syntaxe de la jointure externe :
select [all |distinct]
* | expression
[as colonne_resultat]
{, expression [as colonne_resultat]
}
from source
{ type_jointure join source on
condition_jointure }
[ where .......... ]
où type_jointure peut être : inner |
left | right | full
L'option inner join désigne la jointure interne, les autres
les 3 types de jointures externes.
Dans chaque cas de jointure externe, on désigne la table (ou
vue) qui sera externe, c'est-à-dire dont toutes les lignes seront
affichées; ainsi, en cas de left join, c'est la table de
gauche qui est externe; en cas de right join, c'est celle de droite,
et les deux en cas de full join.
Les jointures peuvent être emboîtées dans une clause
from. Elles sont alors évaluées de gauche à droite.
On peut, en utilisant des parenthèses, forcer l'ordre d'évaluation.
Schémas des jointures externes correspondant aux tables foyer
et véhicule précédentes:
table foyer
|
|
table vehicule
|
|
ident
A1+
|
|
ident
A2
|
jointure externe
complète : A full join B on A.ident =
B.ident
|
NULL
|
|
B2
|
|
B1
|
|
NULL
|
|
exemple : sélection d'informations sur tous les foyers et tous
les véhicules
select f.ident, f.depcom, f.nbpers,
v.an, v.marqmod
from foyer f full join vehicule
v
on f.ident = v.ident
table foyer
|
|
table vehicule
|
|
ident
A1+
|
|
ident
A2
|
jointure externe
gauche : A left join B on A.ident=B.ident
A est la table externe
|
B1
|
|
NULL
|
|
exemple : sélection de tous les foyers et des informations sur
leurs véhicules éventuels
select f.ident, f.depcom, f.nbpers,
v.an, v.marqmod
from foyer f left join vehicule
v
on f.ident = v.ident
table foyer
|
|
table vehicule
|
|
ident
A1+
|
|
ident
A2
|
jointure externe
droite A right join B on A.ident=B.ident
B est la table externe
|
NULL
|
|
B2
|
|
exemple : sélection de tous les véhicules et des informations
sur les foyers éventuels associés
select f.ident, f.depcom, f.nbpers,
v.an, v.marqmod
from foyer f right join vehicule
v on f.ident = v.ident;
III-6 Agrégations
III-6-1 Les fonctions
d'agrégation
Elles opèrent sur une colonne de valeurs.
A l'intérieur de sql, elles sont référencées
comme des Set Functions
Ce sont :
avg sum count max min
elles ne peuvent pas être imbriquées;
elles ne peuvent pas être dans une clause where;
elles ne peuvent être que dans les clauses select et having;
avg, count, sum peuvent avoir l'argument distinct;
les valeurs nulles sont ignorées, sauf pour count(*) qui compte
les lignes.
exemple : sélection de la moyenne du nombre de véhicules
par foyer :
- sans clause where
select avg(nbvoi) as moyenne
from
foyer;
- avec clause where
select avg (nbvoi) as moy_1a2
from
foyer
where nbvoi <= 2;
le where élimine les lignes avec 3 véhicules ou plus
avant calcul de la moyenne.
III-6-2 Agrégats
avec clauses where, group by et having
Trouver le nombre moyen de véhicules par CSP ; on ne s'intéresse
qu'aux foyers ayant au plus 2 véhicules :
select cprof, avg(nbvoi)
from foyer
where nbvoi <= 2
group by cprof ;
En premier le where élimine.
Les lignes restantes sont groupées avant calcul de la moyenne.
Le regroupement peut se faire suivant plusieurs colonnes.
Le select ne peut contenir que des agrégats, ou des constantes
et les colonnes du group by.
exemple : même question que précédemment, mais en
ne s'intéressant qu'aux CSP avec plus de 2 foyers dans la base :
select cprof, avg(nbvoi)
as moy
from foyer
where nbvoi <= 2
group by cprof
having count(ident) >
2;
Les groupes ne satisfaisant pas la clause having sont éliminés.
La clause having doit produire une seule valeur par groupe
III-6-3 Ordre conceptuel
dans lequel les opérations sont effectuées
Dans le cas de la requête précédente :
-
formation du produit cartésien des tables indiquées dans
le from
-
élimination des lignes ne satisfaisant pas le where
-
regroupement des lignes suivant la clause group by
-
élimination des groupes ne satisfaisant pas la clause having
-
évaluation des expressions dans la clause select
-
si select distinct, élimination des lignes en double dans
la table résultat
III-7 Définitions
à propos de select, subselect, et subquery
Tout ce qui commence par select est un "subselect" .
Un subquery n'apparaît que dans une condition de recherche,
il est introduit par, et seulement par :
any | all,
in | not in,
[not] exists
un ordre select est l'union de subselect(s) :
select ident from foy84
union
select ident from foy86 where
ident in
( select ident from vehicule
where ancstr >= 2);
Cet ordre select contient 3 subselect et 1 subquery .
Il y a toujours deux façons d'écrire une même requête
mettant en oeuvre plus d'une table :
- avec jointure
- avec subquery
III-8 Création de
table
III-8-1 Syntaxe de l'ordre
create table
On ne crée que la structure de la table, sans données.
create table [schema.]nom_tab (
(colonne_spec {, colonne_spec })
[, [constraint nom_contrainte] contrainte_table
{, [constraint nom_contrainte] contrainte_table}
[with with_clause])
colonne_spec peut être :
nom_colonne type
[[with] default default_spec
| with default | not default]
[with null | not null]
[[constraint nom_contrainte] contrainte_colonne
{, [constraint nom_contrainte] contrainte_colonne}]
où type fait partie des types vus au paragraphe III-1-4;
avec le type "logical key", on peut ajouter la clause "with
system maintained"
III-8-2 Valeurs nulles
et par défaut des colonnes
not default spécifie que la valeur de la colonne doit
être définie;
with default spécifie que si aucune valeur n'est
fournie, on aura 0 pour les types numériques et money, une chaîne
vide pour les types caractères et date;
[with default] default_spec spécifie la valeur
que prend la colonne par défaut si elle n'est pas fournie;
exemple :
create table dept(dnom char(10),
location char(10) default
'PARIS',
creation date default '01/01/97',
budget money default 10000);
with null spécifie que la colonne accepte les valeurs nulles;
not null spécifie que la colonne ne peut pas prendre la
valeur "null";
Lorsque l'on autorise la valeur logique 'null' pour une colonne,
un octet est rajouté pour le stockage de cette colonne dans chaque
ligne de la table.
exemple :
create table foyer
(ident integer not null not default,
an integer2,
depcom integer,
nbpers integer1,
cnaiss integer1,
cprof integer1,
nbvoi integer1,
revenu integer1,
ponder float4
);
Combinaison de la clause with | not null avec la clause with
| not default :
with null |
La colonne accepte les valeurs nulles. Si aucune
valeur n'est fournie, Ingres insère "null". |
with null with default |
La colonne accepte les valeurs nulles. Si aucune
valeur n'est fournie, Ingres insère un 0 ou chaîne vide selon
le type. |
with null not default |
La colonne accepte les valeurs nulles. L'utilisateur
doit fournir une valeur |
not null with default |
La colonne n'accepte pas les valeurs nulles.
Si aucune valeur n'est fournie, Ingres insère un 0 ou chaîne
vide selon le type |
not null not default ou not null |
La colonne est obligatoirement renseignée
et n'accepte pas les valeurs nulles, cas des colonnes de type "primary
key", par exemple. |
Avec "with system maintained", la seule clause de défaut
valide est "with default". Elle est prise par défaut si vous
l'oubliez. La seule clause de nullité valide est "not null".
Si vous ne spécifiez pas de contrainte de colonne ou de clause de
nullité, la clause "not null" est prise par défaut.
III-8-3 Contraintes sur
les colonnes
contrainte_colonne permet de définir les contraintes de colonnes
suivantes :
-
unique spécifie que l'on ne peut pas avoir deux lignes avec
la même valeur de colonne;
-
check (controle_spec) définit une condition que doit vérifier
la colonne
exemple
create table emps (nom char(25),
sal money,
constraint cont_sal check
(sal > 0));
la contrainte définit la condition salaire positif;
-
references [schema.]nom_tab[(nom_col)] définit une contrainte
référentielle entre la colonne et une colonne d'une autre
table;
exemple :
create table emp (enom char(10),
edept char(10) references
dept(dnom));
la contrainte référentielle définie ici assure qu'un
employé ne peut avoir un département non présent dans
la table "dept";
-
primary key spécifie que la colonne est une clé primaire
(une seule possible par table) et qu'une contrainte référentielle
dans une autre table pourra y faire référence;
exemple :
table référencée :
create table partenaires (partno
intprimary
key...);
table qui la référence :
create table liste (ipartno int...
foreign key (ipartno) references
(partenaires));
dans la table "liste", ipartno est une clé externe, liée
par contrainte référentielle à la table "partenaire",
c'est-à-dire, automatiquement, à la clé primaire qui
a été définie dans cette table;
III-8-4 Contraintes sur
les tables
Une contrainte au niveau de table peut être :
-
unique(nom_col {, nom_col) permet de spécifier que les données
d'un groupe de colonnes sont uniques;
exemple :
create table depts(dnom
char(10)
not
null,
dlocation char(10) not null)
constraint unique_dept unique
(dname,
dlocation));
La contrainte de nom "unique-dept" assure que 2 départements de
même localisation ne peuvent avoir le même nom. Les colonnes
sont obligatoirement déclarées "not null";
-
check (controle_spec) permet de spécifier une condition à
vérifier pour un groupe de colonnes;
exemple :
create table dept ( dnom char(10),
location char(10),
budget money,
depenses money,
constraint cont_montant check
(budget > and
depenses <= budget));
Cette contrainte assure que chaque département a un budget et que
les dépenses n'excèdent pas le budget.
-
references [schema.]nom_tab[(nom_col {, nom_col})] permet de spécifier
des contraintes référentielles au niveau de la table, en
utilisant l'option "foreign key"
exemple :
create table chef (nom char(10),
empno char(5),
...
foreign key (nom, empno) references
emp);
Cette contrainte vérifie le contenu des colonnes "nom" et "empno"
par rapport aux colonnes correspondantes de la table "emp" pour assurer
que quiconque entré dans la table "chef" est un employé de
la table "emp". Puisque le nom de la colonne référencée
est omis, la table "emp" doit avoir une contrainte de "primary key" qui
définit les colonnes nom et empno.
III-8-5 Clause with du
create table
Les options possibles sont :
-
location = (disc-logic-i {, disc-logic-i }) spécifie les
localisations de la table; ceci permet de répartir les données
sur différents disques, si l'administrateur Ingres l'a prévu;
-
[no]journaling spécifie avec ou sans journalisation de la
table
cette option ne prend effet qu'après lancement, au niveau Unix
de la commande ckpdb. Il n'y a pas de journalisation par défaut;
-
[no]duplicates permet ou pas les lignes doubles
cette option ne prend effet qu'après modification de la structure
physique par la requête modify, doubles autorisés par
défaut;
-
label_granularity = table | row | system_default spécifie
le niveau du label de sécurité;
-
security_audit = (audit_opt {, audit_opt}) spécifie un niveau
d'audit par ligne (audit_opt=row) ou par table (audit_opt=table);
-
security_audit_key = (nom_col) cette option permet de spécifier
un attribut qui sera écrit dans le fichier log de l'audit; par exemple
on utilise le numéro d'employé comme clé d'audit
create table employe (nom
char(60),
emp_no integer)
with security_audit = (table,
row),
security_audit_key = (emp_no);
III-8-6 Limitations
nom de table <= 32 caractères
nom de colonne <= 32 caractères
au plus 300 colonnes par table
au plus 2008 octets par ligne, sauf pour les colonnes de type "blob"
(binary long object), long varchar et long byte, qui peuvent
aller jusqu'à 2 gigaoctets.
III-9 Création de
table à partir d'une recherche
Le résultat d'une recherche est une table; on peut
l'affecter à une table, temporaire ou permanente et les types
des colonnes de la nouvelle table correspondent au type calculé
dans le select, ce qui peut permettre des conversions de type dans
certains cas. Il est également possible de renommer les colonnes
de la nouvelle table; il n'est par contre pas possible de leur assigner
un type.
III-9-1 Syntaxe de create
table
create table nom_table [(nom_col1, nom_col2,..)]
as select ...
[with with_clause];
exemple : on crée la table des "sur-motorisés" avec les foyers
ayant au moins 3 véhicules
create table sur_mot
as select * from foyer
where
nbvoy >= 3 ;
La table sur_mot est créée et chargée avec
les lignes sélectionnées, le nom des colonnes reste inchangé.
III-9-2 Options supplémentaires
de la clause with
-
structure = hash | heap | isam | btree spécifie la structure
de stockage de la table (voir le chapitre optimisations)
-
key = (nom_col {, nom_col}) spécifie les colonnes servant
de clés
-
fillfactor = n spécifie le pourcentage de remplissage des
pages de données primaires (voir modify)
-
minpages = n spécifie le nombre minimum de pages primaires
pour une table en "hash"(voir modify)
-
maxpages = n spécifie le nombre maximum de pages primaires
pour une table en "hash"(voir modify)
-
leaffill = n spécifie le pourcentage de remplissage
des pages d'index "feuilles" en BTREE (voir modify)
-
nonleaffill = n spécifie le pourcentage de remplissage
des pages d'index "non feuilles" en BTREE (voir modify)
-
compression[= ([[no]key] [,[no]data])] | nocompression spécifie
si la clé ou les données sont compressées
-
allocation =n spécifie le nombre de pages initialement allouées
à la table (4 par défaut)
-
extend =n spécifie le nombre de pages pour l'extension de
la table (16 par défaut)
III-10 Création
de tables temporaires
OpenIngres permet la création de tables temporaires,
qui :
- existent pour la durée de la session,
- sont automatiquement détruites à la fin de la session.
Le nom de la session fait partie du nom de la table, ce qui élimine
les conflits de noms.
L'accès à ces tables est rapide, car elles sont, autant
que possible, conservées en mémoire :
- pas de privilèges à vérifier,
- pas d'entrées de catalogues à parcourir,
- pas de logging ou de locking à gérer (ni sauvegarde,
ni verrouillage).
Restrictions
- elles ne sont visibles que de la session qui les a créées,
- elles disparaissent à la fin de la session,
- on ne peut leur appliquer que les instructions modify et drop.
Syntaxe :
création d'une table temporaire originelle
declare global temporary table session.table_name
(nom_col format {, nom_col format})
on commit preserve rows
with norecovery
[with_clause]
création d'une table temporaire à partir d'une autre table,
avec un "subselect"
declare global temporary table session.table_name
(nom_col {, nom_col})
as subselect
on commit preserve rows
with norecovery
[with with_clause]
Options possibles de with_clause :
location = (nom_loc {, nom_loc})
[no]duplicates
allocation = n
extend =n
Pour les tables temporaires créées avec un subselect,
les options suivantes peuvent être utilisées dans with_clause:
structure = hash | heap | isam | btree
key = (liste_col)
fillfactor = n
minpages = n
maxpages = n
leaffill = n
nonleaffill = n
compression[ = ([[no]key] [,[no]data])]
| nocompression
Vous pouvez donner à une table temporaire le même nom qu'une
table permanente. Par exemple, pour l'utilisateur "jules", une table permanente
matable sera nommée par le système "jules.matable" et la
table temporaire de nom "matable" sera nommée par le système
"session.matable".
III-11 Création
de vue
Une vue est une définition logique, sans stockage
de données. Cela permet des calculs (et/ou jointures) sur des données
qui sont refaits à chaque appel, prenant en compte toutes les modifications
intervenues dans les données. Seule la définition est stockée
(accessible par help view nom_vue).
create view nom_vue [(nom_col1, nom_col2,..)]
as select ...;
[with check option]
exemple : créer la vue des foyers "sur-motorisés"
create view sur_mot
as select * from foyer
where
nbvoy >= 3 ;
La clause facultative with check option permet de définir,,
lors de la mise à jour de données via la vue, que la (les)
conditions de la clause where doit être vérifiée. Si
elle n'est pas présente, aucune vérification ne sera faite.
Avec cette clause, on peut insérer des lignes, mettre à
jour des colonnes, par l'intermédiaire d'une vue, si les conditions
du where sont respectées
exemple : créer la vue des foyers de Paris
create view foyerparis as
select ident, depcom, an
from foyer85
where depcom/1000 = 75 with check
option;
L'insertion suivante échouera
insert into foyerparis values
(90168 , 93063, 84);
L'insertion suivante réussira
insert into foyerparis values
(90168 , 75114, 84);
Une vue s'utilise comme une table, mais les opérations qu'elle sous-tend
sont effectuées à chaque appel.
exemple : recherche dans la vue "sur_mot"
select * from sur_mot where
dep = '87';
III-12 Destruction d'une
table ou d'une vue
drop nom_table | nom_vue | nom_index{,
nom_table | nom_vue | nom_index} ;ou
drop table nom_table {,nom_table};
drop view nom_vue {,nom_vue} ;
drop index nom_index {,nom_index} ;
La destruction d'une table n'est possible que par son propriétaire
ou l'administrateur, elle est effectuée sans demande de confirmation
et détruit à la fois le contenu de la table(toutes
les lignes) et le schéma de la table. Les
droits,
intégrités, règles et vues référençant
une table seront également détruits sans avertissement. Voir
les outils d'export de base pour sauvegarder les définitions sql
d'une base (avant la destruction d'une table).
exemple : destruction de la table "commune"
drop table commune ;
Quand l'une des tables ayant servi à la définition d'une
vue est détruite, la vue est également détruite.
III-13 Mise à jour
de table
III-13-1 Ajout de lignes
dans une table
On peut ajouter à une table des lignes créées
comme résultats d'une recherche
insert into nom_table [(col1, coli)]
select
...
;
exemple : insertion de lignes dans "commune", depuis des lignes de la table
"com_ext"
insert into commune
select depc, depc / 1000,
0, psdc, comclair
from com_ext
where depc / 1000 = 95
;
Autre forme moins utilisée, car elle ne permet l'ajout que d'une
seule ligne à la fois :
insert into nom_table [(col1, coli,
)] values (exp1, expi ) ;
exemple : insertion d'une ligne dans "commune"
insert into commune (depcom, dept,
tranche, psdc, comclair)
values (94060,94,2,849,'Queue-en-Brie');
Pour les deux formes, les colonnes non spécifiées prennent
la valeur null, si celle-ci est permise.
III-13-2 Destruction
de lignes d'une table
delete from nom_table [where
cond_rech] ;
exemple : destruction des lignes de "commune" correspondant à la
tranche inférieure à 2
delete from commune where
tranche <= 2 ;
C'est une destruction "logique".
III-13-3 Mise à
jour de lignes d'une table
update nom_table [syn] [from
nom_table1 [syn1] {,nom_table2 [syn]}]
set coli = expi {, colj = expj}
[ where cond_rech] ;
exemple : mise à jour de la variable psdc pour la commune ayant
depcom = 94060
update commune
set psdc = 9722
where depcom = 94060;
exemple : mise à jour de la variable ponder des foyers en fonction
de la variable tranche de leur commune
update foyer f from commune
c
set ponder = ponder + float4(c.tranche)
/
10.0
where c.depcom = f.depcom
;
III-14 Commentaires
sur les tables et les colonnesIls permettent une documentation
interne à la base, et sont chargés/déchargés
par unloaddb et copydb. La taille d'un commentaire est limitée
à 1600 caractères.
Création :
comment on table [schema.]nom_tab
is
'comment'
comment on column [schema.]nom_col is
'comment'
exemples :
comment on table foyer is
'décrit les ménages du panel SOFRES depuis l''année
1978';
comment on column depcom is
'nombre à 5 chiffres, les 2 plus à gauche représentent
le département, le reste le numéro de commune';
Destruction :
comment on table [schema.]nom_tab
is
''
comment on column [schema.]nom_col is
''
Pour savoir ce que contient le commentaire :
help comment table [schema.]nom_tab
{, [schema.]nom_tab}
help comment column [schema.]nom_tab nom_col
{, nom_col}
Les commentaires sont stockés dans le catalogue système iidbms_comments.
C'est un premier pas vers la documentation d'une base (en dehors des outils
développés par le CIR) mais la grande rigidité de
cette requête sql ne facilite pas son utilisation.
III-15 Chargement et déchargement
de tables (export/import)
La commande copy table permet de charger une table
à partir d'un fichier ou de la décharger dans un fichier.
Le descripteur de format de lecture - écriture est très
simple.
Le format est indépendant du type de colonne.
Syntaxe :
copy [table] nom_table
(col = format [with null [(value)]]
{ ,col = format [with null [( value)
] ] } )
into | from 'chemin_fichier'
[with option {,option} ] ;
Les formats de lecture :
char(0) |
lit tout type de colonne, jusqu'à
la rencontre d'une virgule, tabulation ou retour chariot |
c0 |
comme char(0), mais n'est plus documenté |
char(N) |
1<N<2000, lit tout type de colonne sur
une longueur de N caractères |
cN |
comme char(N), mais n'est plus documenté |
dN |
saut de N caractères dans le fichier,
à associer à une colonne bidon; |
Les formats peuvent s'écrire aussi en précisant un délimiteur
de champ autre que la virgule (tabulation, retour chariot), il faut alors
le préciser notamment après char(0) ou c0.
ex : char(0)'?'
Certains caractères spéciaux sont représentés
par un mot clé :
nl |
retour chariot |
tab |
caractère de tabulation |
sp |
espace |
comma |
virgule |
colon |
deux points |
Il faut absolument faire figurer, dans le format de lecture,
le délimiteur de ligne au bon endroit (char(0)nl dans l'exemple
qui suit). Ces formats peuvent être utilisés également
en écriture pour exporter des données, mais il existe des
outils Ingres et CIR pour le faire plus aisément.
exemple de contenu du fichier à importer :
94033,94,2,51868,Fontenay-sous-Bois
94075,94,2,7921,Villecresnes
copy table commune (
depcom = char(0),
dept = char(0),
tranche = char(0),
psdc = char(0),
comclair = char(0)nl)
from ' /serveur/cir/dest/com.fich'
;
Autre exemple : les données sont formatées
94033 94 2 ??? 51868 Fontenay-sous-Bois
94075 94 2 +++ 7921 Villecresnes
copy table commune (
depcom = char(5),
dept = char(5),
tranche = char(2) with null('X'),
xx = d4,
psdc = char(7),
yy = d1,
comclair = char(20)nl)
from 'com2.don'
with on_error = continue,
log=
'fich_erreurs'
;
Les deux options du with sont intéressantes lorsque l'on
n'est pas sûr des données, elles permettent de continuer la
copie, même en cas d'erreur, et de stocker toutes les lignes erronées
dans un fichier d'erreur, qui, corrigé, pourra lui-même servir
de fichier de données.
La table suivante explicite les formats de données des fichiers
par rapport aux types de données SQL.
Format |
Stockage (Copy Into) |
Lecture (Copy From) |
byte(0) |
donnée binaire de longueur
fixe (complétée de zéros si nécessaire). |
donnée binaire de longueur
variable terminée par la première virgule, tabulation ou
fin de ligne rencontrée. |
byte(0)delim |
donnée binaire de longueur fixe (complétée
de zéros si nécessaire). Le délimiteur sur 1 caractère
est inséré immédiatement après la valeur (zéro
n'est pas un délimiteur autorisé). |
donnée binaire de longueur variable terminée
par le caractère spécifié. |
byte(n) où 1< n <
2000 |
donnée binaire de longueur fixe |
donnée binaire de longueur fixe |
byte varying(0) |
donnée binaire de longueur variable précédée
d'une longueur sur 5 car. |
donnée binaire de longueur variable précédée
d'une longueur sur 5 car. |
byte varying(n)
où 1< n < 2000 |
donnée binaire de longueur fixe précédée
d'une longueur sur 5 car. Complétée par des zéros
si nécessaire |
donnée binaire de longueur fixe précédée
d'une longueur sur 5 car. |
char(0) |
Chaîne de longueur fixe, complétée
par des blancs si nécessaire. Pour les données character,
la longueur de la chaîne écrite dans le fichier est la même
que la longueur de la colonne |
chaîne de longueur variable terminée
par la première virgule, tabulation ou fin de ligne rencontrée. |
char(0)delim |
Complété à la longueur
déclarée de la colonne. Le délimiteur sur 1 caractère
est inséré immédiatement après la valeur (un
espace n'est pas un délimiteur autorisé). |
chaîne de longueur variable terminée
par le caractère spécifié. |
char(n) où 1< n <
2000 |
Chaîne de longueur fixe |
Chaîne de longueur fixe |
d0 |
(non applicable) |
Champ bidon. Chaîne de longueur variable
terminée par la première virgule, tabulation ou fin de ligne
rencontrée. La donnée dans le champ est sautée |
Format |
Stockage (Copy Into) |
Lecture (Copy From) |
d0delim |
Indique une colonne bidon délimitée.
Au lieu de mettre une valeur dans le fichier, copy insère le délimiteur
spécifié. (Contrairement au format dn, ce format n'insère
pas le nom de colonne.) |
champ bidon : lu comme une chaîne de longueur
variable délimitée par le caractère spécifié.
La donnée dans le champ est sautée. |
date |
donnée de format date. |
Champ date. |
decimal |
donnée de format decimal |
donnée de type decimal. |
dn |
Indique une colonne bidon délimitée.
Au lieu de mettre une valeur dans le fichier, copy insère le nom
de la colonne n fois. Par exemple, si vous spécifiez x=d1, le nom
de colonne 'x' est inséré une fois, si vous spécifiez
x=d2, le nom de colonne 'x' est inséré deux fois, etc. Vous
pouvez spécifier un délimiteur comme nom de colonne, par
exemple, nl=d1. |
champ bidon : lu comme une chaîne de longueur
variable de la longueur spécifiée. La donnée dans
le champ est sautée. |
float |
flottant double précision |
flottant double précision |
float4 |
flottant simple précision |
flottant simple précision |
integer |
entier sur 4 octets |
entier sur 4 octets |
integer1 |
entier sur 1 octet |
entier sur 1 octet |
long byte(0) |
Donnée binaire stockée dans des
segments. Chaque segment est composé d'un entier, donnant la longueur
du segment, suivi par un espace, puis par le nombre de bytes spécifié.
Si la colonne peut avoir la valeur null, il faut spécifier la clause
"with null". Une colonne vide est stockée comme un 0 suivi par un
espace. |
Champ de type long byte. |
Format |
Stockage (Copy Into) |
Lecture (Copy From) |
long varchar(0) |
Donnée stockée dans des segments.
Chaque segment est composé d'un entier, donnant la longueur du segment,
suivi par un espace, puis par le nombre de caractères spécifié.
Exemple de 2 segments : le premier segment a 5 caractères et le
second a 10 caractères :
5 abcde
10 abcdefghij...
Si la colonne peut avoir la valeur null, il faut spécifier la
clause "with null". Une colonne vide est stockée comme un 0 suivi
par un espace. |
Champ de type long varchar |
money |
donnée de format. money |
champ de format. money |
smallint |
entier sur 2 octets |
entier sur 2 octets |
varchar(0) |
chaîne de longueur variable précédée
de 5-characteres donnant la longueur |
chaîne de longueur variable précédée
de 5-characteres donnant la longueur |
varchar(n)
où 1<n< 2000 |
chaîne de longueur fixe précédée
de 5-characteres donnant la longueur. Complétée si nécessaire
par des caractères null |
chaîne de longueur fixe précédée
de 5-characteres donnant la longueur. |
III-16 Sécurité
des données
III-16-1 Privilèges
dans l'environnement OpenIngres
Les privilèges définissent les opérations qu'un usager
peut exécuter. Ils sont mis en oeuvre via l'usage de permissions.
Les permissions autorisent ou interdisent à un usager l'exécution
d'opérations.
On distingue :
-
des privilèges utilisateurs que l'usager peut exécuter dans
l'installation OpenIngres.
-
des privilèges sur les objets d'une base.
-
des privilèges de base et d'installation, décrivant les opérations
que l'usager peut exécuter ou non, et pouvant être définis
pour les bases individuelles ou pour toutes les bases de l'installation
OpenIngres.
On peut maintenant avoir les pouvoirs de l'administrateur d'une base sans
être soi-même administrateur, et donner des privilèges
d'accès aux objets privés n'appartenant pas à l'administrateur,
ainsi que transmettre des privilèges.
Les contrôles d'accès par les vues sont étendus
à d'autres fonctionnalités, permettant de gérer les
accès sur les colonnes.
Enfin les privilèges sur les bases et l'installation OpenIngres
permettent une gestion plus précise des privilèges.
III-16-2 Privilèges
objets
Ils donnent les opérations qui peuvent être exécutées
sur les objets d'une base de données.
Avec l'ancienne version de Ingres, les privilèges se rapportaient
seulement aux objets que possédait l'administrateur de la base,
les objets possédés par d'autres utilisateurs étaient
toujours privés.
Avec OpenIngres tout utilisateur peut accorder des privilèges
sur les objets qu'il possède, et ce à n'importe quel autre
usager.
Les privilèges objets sont manipulés en utilisant les
ordres SQL grant et revoke, qui sont les ordres de la norme
ANSI pour la manipulation de privilèges.
create/drop/permit sont les ordres spécifiques à
Ingres, et sont retirés progressivement
(revoke et drop permit se comportent différemment).
III-16-2-1 l'ordre grant
L'option grant donne aux utilisateurs, groupes et rôles les privilèges
sur les tables, vues, procédures, événements, bases
et l'installation OpenIngres courante.
grant all [privileges] | privilege
{, privilege}
|role {, role}
[excluding (nom_col {, nom_col})]
[on [type_objet] [schema.]nom_objet}]
to public | [type_autoris] id_autoris
{, id_autoris}
[with grant option]
privilege est un mot clé qui peut être :
select
update
delete
insert
execute (uniquement pour les procédures, droit unique
des procédures)
references donne le droit à créer des contraintes
référentielles sur les tables et colonnes spécifiées
copy_into
copy_from
all [privileges] tous les droits (doit être seul présent)
type_objet peut être :
table
procedure
database
dbevent
current installation
Par défaut, le type d'objet est "table". Le privilège
possible dépend du type d'objet
nom_objet est le nom de l'objet désigné
type_autoris est le type d'autorisation à qui vous donnez les
privileges :
user (par défaut)
group
rôle
id_autoris est le nom de users, groups, ou roles à qui vous donnez
les privileges, ou public (droit accordé à tous).
exemple : on met l'accès en lecture à tous sur la table
"commune"
grant select on commune
to
public;
exemple : on met l'accès en lecture et mis à jour à
l'usager bl sur la table "commune"
grant insert, update on
commune to bl;
Les usagers peuvent toujours donner les accès sur les tables et
les événements des bases qu'ils possèdent.
Avec "with grant option", les usagers peuvent déléguer
(en cascade) à d'autres usagers le droit de donner des accès
aux objets, pour les mêmes privilèges qu'on leur a donnés
(ceci s'applique donc aux objets possédés par d'autres usagers).
Exemple : passage de privilèges
Rémy :
grant select, insert on remy.dept
to
line with grant option
Line :
grant select on remy.dept to
michel with grant option
Michel :
grant select on remy.dept toalain
Rémy, Michel, Line et Alain peuvent faire des sélections
de la table remy.dept possédée par Rémy.
Rémy et Line peuvent insérer dans cette table.
Rémy, Michel et Line peuvent donner toutes les permissions aux
autres usagers, Alain ne peut pas.
with grant option n'est pas valide pour les permissions données
aux groupes et rôles, ni pour les permissions données sur
les bases ou sur l'installation courante.
III-16-2-2 suppression de privilèges
Dans la version OpenIngres, les privilèges sont supprimés
en utilisant l'ordre SQL revoke, remplaçant l'ordre drop permit
revoke [grant optionfor]
all
[privileges] | privilege {, privilege}
[excluding (nom_col {, nom_col},)]
on [type_objet [schema.]nom_objet {,
[schema.]nom_objet}
| current installation from public
| [type_autoris] id_autoris {, id_autoris}
cascade
| restrict
Attention, l'un des mots-clés cascade ou restrict
doit forcément être présent, sauf si on supprime le
privilège sur une base ou sur l'installation courante.
cascade enlève le privilège à supprimer,
et aussi tous ceux qui en découlent.
restrict enlève le privilège spécifié
seulement s'il n'y a pas d'autres privilèges dépendants :
ceci évite d'avoir des privilèges "orphelins".
On ne peut supprimer que les privilèges qu'on a soi-même
donnés.
On peut enlever le privilège "with grant option".
On peut ôter en cascade les privilèges dépendants.
Drop permit
Peut toujours être utilisé pour enlever les privilèges.
Nécessite d'être le propriétaire de l'objet, mais
pas nécessairement le donneur d'accès.
Echoue si un privilège ou objet quelconque est abandonné.
with grant option
III-16-2-3 privilèges dépendants
Donner des permissions à d'autres usagers affecte les chaînes
de permissions et les permissions dépendantes.
Ainsi, de l'exemple précédent :
Le privilège select de Michel sur remy.dept dépend de
Line ayant à la fois les droits select et grant option
Si les droits select ou grant option de Line sont supprimés,
la permission select de Michel l'est également. On peut donc faire
:
revoke grant option for select on
remy.dept
from line cascade ;
ou :
revoke select on remy.dept
from line cascade ;
III-16-2-4 vues et privilèges
La création de vues nécessite le privilège
de sélectionner sur toutes les tables ou vues sur lesquelles la
vue est basée.
Donner un droit sur une vue nécessite de pouvoir donner les permissions
désirées sur toutes les tables ou vues de la base.
Le mieux est d'avoir le privilège grant option sur les
autres tables ou vues.
La définition d'un privilège sur une vue est transmissible.
III-16-2-5 procédures de
bases de données et privilèges
Le propriétaire d'une procédure de base de données
doit posséder les objets que celle-ci utilise ou avoir les privilèges
sur les objets qu'elle nécessite.
Elles sont parfois appelées procédures de base de données
"actives".
La procédure de base de données devient "dormante" si
les conditions changent après la création de la procédure
de base de données (suppression de privilèges, par exemple
...).
Le propriétaire doit posséder le privilège grant
option sur tous les objets référencés dans la
procédure de base de données pour y donner les privilèges
à d'autres usagers (elles sont appelées procédures
autorisables).
III-16-2-6 privilège de mise
à jour multicolonne
grant permet de restreindre la mise à jour aux colonnes :
soit la table : vendeur (vnom, vnum, rue, ville, dept, code) :
grant select on vendeur to public
;
grant update (vnom, rue, ville, dept,
code)
on vendeur to public ;
la colonne vnum ne peut pas être modifiée.
Le privilège revoke update est utilisable pour les colonnes
:
revoke update (vnom) on vendeur
from public ;
vnom ne peut plus être modifiée, les colonnes restantes sont
toujours modifiables.
revoke excluding ne laisse qu'un privilège intact :
revoke update excluding (rue)
on vendeur from public restrict ;
seule la colonne rue peut encore être modifiée.
III-16-3 Privilèges
utilisateurs
III-16-3-1 présentation
Il y a 6 principaux privilèges utilisateurs, qui concernent en fait
seulement l'administration de base ou d'installation Ingres :
Security Administrator (Administrateur de la Sécurité)
Equivalent au SuperUser des versions Ingres précédentes,
donne tous les droits. Create Database (création de base)
Habilitation à créer des bases. Set Trace Flags (mettre
des traces)
Possibilité de faire des "trace flags" ou des "trace points".
Operator (Opérateur)
Possibilité d'exécuter checkpoint (point de reprise) et
rollforward (recharge de la base à partir de checkpoint) tout comme
l'administrateur de la base. Maintain locations
Possibilité de gérer les locations pour l'installation.
Audit all activity (journalisation de l'ensemble de l'activité)
Tous les accès d'enregistrements effectués par les usagers
ayant ce droit seront écrits dans le fichier d'audit.
III-16-3-2 opérations et
syntaxe
On donne (grant) et retire (revoke) les privilèges
via accessdb.
On peut aussi les manipuler via les nouvelles commandes SQL :
create/alter/drop user : créer, modifier, détruire
un usager
ceci nécessite d'avoir le privilège "Security Administrator"
et doit être effectué à partir d'une session connectée
à la base maître iidbdb.
Syntaxe des privilèges utilisateurs :
create user nom_usager
[with [group = id_groupe | nogroup]
[,privileges =(privilege{,privilege})|noprivileges]]
;
alter user nom_usager
[with [group = id_groupe | nogroup]
[,privileges =(privilege{,privilege})|noprivileges]]
;
drop user nom_usager;
III-16-3-3 gestion des locations
Ils concernent l'administration de l'installation OpenIngres.
Les usagers ayant le privilège "maintain locations" peuvent
gérer les locations :
par accessdb.
ou par les nouveaux ordres SQL :
create location nom_location with
area = nom_disque
[, usage = (type_usage {, type_usage})
| nousage];
alter location nom_location with
area = nom_disque
[, usage = (type_usage {, type_usage})
| nousage];
alter location ne change pas l'usage pour une base utilisant déjà
la location nommée.
alter location remplace le précédent usage d'une
location et n'est pas cumulatif.
drop location nom_location ;
on ne peut détruire une location utilisée par une autre base.
III-16-4 Contrôle
d'accès par les vues
L'ordre SQL grant a des possibilités limitées pour le contrôle
d'accès aux colonnes :
on peut préciser les colonnes qu'un usager peut modifier, mais
on ne peut pas préciser les colonnes qu'un usager peut sélectionner.
Les vues fournissent une restriction horizontale et verticale de l'accès
aux données usager
Le privilège select sur une vue n'implique pas le privilège
select sur les tables sur lesquelles cette vue est basée.
Exemple : permettre à chaque usager de voir les noms et salaires
des employés qu'il gère :
create view v_emp as select
nom, salaire
from emp where gest = dbmsinfo('user_name')
;
grant select on v_emp to public
;
Tous les usagers peuvent effectuer des sélections depuis la vue
v_emp.
Chaque usager voit seulement les articles des employés qu'il
gère, son nom étant alors dans la colonne 'gest'.
III-16-5 Privilèges
sur une base et sur l'installation
III-16-5-1 généralités
Ces privilèges ne concernent pas l'utilisateur final, sauf s'il
est aussi administrateur de base. Certains privilèges peuvent être
donnés tantôt sur une base, tantôt sur l'installation
OpenIngres entière.
Ils ne s'appliquent pas aux administrateurs de base sur leurs propres
bases.
Ils ne s'appliquent pas aux administrateurs sécurité dans
l'installation OpenIngres entière.
Les privilèges peuvent être actifs ou inactifs.
Le niveau base prévaut sur le niveau installation (on peut autoriser
localement une permission au niveau base alors qu'elle est ôtée
au niveau installation).
III-16-5-2 privilèges sur
une base et l'installation complète
Les privilèges sur une base sont gérés soit par l'administrateur
de la base concernée, soit par l'administrateur système OpenIngres,
soit par tout usager ayant le privilège "Security Administrator"
Les privilèges sur l'installation OpenIngres sont gérés
soit par l'administrateur système OpenIngres, soit par tout usager
ayant le privilège "Security Administrator"
Tout ceci doit être effectué dans une session "terminal
monitor" connectée à la base iidbdb.
[no]access |
interdit/autorise l'accès usager |
[no]create_table |
interdit/autorise la création de tables |
[no]create_procedure |
interdit/autorise la création de procédures |
[no]lockmode |
interdit/autorise le changement de l'état
du verrouillage |
[no]query_row_limit |
libère/limite le nombre de lignes qu'une
requête peut fournir |
[no]query_io_limit |
libère/limite le nombre d'entrées-sorties
possibles pour une requête |
[no]db_admin |
interdit/autorise la possibilité d'agir
comme un DBA |
[no]update_syscat |
interdit/autorise la possibilité de modifier
les catalogues systèmes |
On donne ou enlève ces privilèges en utilisant grant
et revoke.
Pour donner les privilèges de base et d'installation :
grant base_priv {,base_priv}
on database nom_base | current installation
to
[role | user | group] identifier |
public
;
pour ôter les privilèges de base et d'installation :
revoke base_priv {,base_priv}
on database nom_base | current installation
from [role | user | group] identifier
| public ;
III-16-5-3 exemples
grant nocreate_table
on current installation to public ;
grant nocreate_procedure
on current installation to public ;
grant create_table, create_procedure
on database basetest to public
;
grant query_row_limit 100
on current installation to user remy
;
revoke query_row_limit
on current installation from user
remy ;
III-17 Les contraintes
d'intégrité
III-17-1 Créer
une contrainte d'intégrité
create integrity on nom_tab is
cond_recherche ;
Restrictions : la condition de recherche ne peut porter que sur la tablenom_tab,
sans subselect, ni agrégat.
exemple : la variable dept de commune doit être comprise entre
00 et 98
create integrity on commune is
dept between 00 and 98;
III-17-2 Lister les
contraintes d'intégrité
help integrity nom_tab ;
Les contraintes d'intégrité sont numérotées.
III-17-3 Détruire
les intégrités en indiquant leurs numéros
drop integrity on nom_tab n1
{, n2} ;
III-18 Gestions d'événements,
règles et procédures
III-18-1 Introduction
Ingres sait gérer en interne des déclenchements
automatiques d'ensemble d'actions pré-programmées en langage
sql (étendu) lorsque certains événements surviennent
dans la base.
Une règle dira lors d'un événement
dans la base de données, c'est à dire une insertion, une
mise à jour ou une destruction, quel ensemble d'actions entreprendre
; cet ensemble d'actions est contenu dans des procédures,
qui sont nommées et paramétrables.
On gère ces objets comme des tables, avec des ordres de création,
de description, de destruction, et de gestion des droits (pour les procédures
uniquement).
Ces règles permettent de créer des contraintes d'intégrité
référentielles : par exemple, interdire la suppression d'un
client de la table client s'il a encore des factures en cours dans la table
facture.
Une autre utilisation permet, comme nous le verrons, de déclencher
des mises à jour en cascade, ce qui peut permettre de retrouver
une arborescence (comme la recherche de descendants dans un arbre généalogique).
III-18-2 Gestion des
procédures
L'ordre de création d'une procédure est le suivant :
[create] procedure [schema.]nom_proc
[(nom_param [=] type_param [with
| not default] [with | not null]
{, nom_param [=] type_param} [with |
not
default][with | not null])]
=|as declare
[declare_section]
begin
ordre {; ordre}[;]
end
Description des paramètres :
nom_proc est le nom de la procedure;
nom_param est le nom d'un paramètre de la procédure; les
paramètres peuvent être passés par valeur ou par référence;
type_param est le type du paramètre;
declare_section est une liste de variables locales à la procedure;
ordre : ordre SQL
Une procédure peut avoir zéro ou plusieurs paramètres
d'entrée (nom_param), dont on doit préciser le type.
On doit indiquer ensuite après l'ordre declare, la liste
des variables internes à la procédure, et leur type détaillé.
Puis vient, à l'intérieur d'un bloc begin-end,
la suite des ordres à effectuer.
Certaines séquences de programmation sont possibles, en dehors
des ordres sql usuels, comme les blocs if-then-else et les blocs
while-endwhile.
Deux ordres sql sont interdits seulement pour le déclenchement
par des règles : commit, et rollback.
On peut utiliser également des ordres de mise en erreur de l'événement
déclencheur, avec message à l'utilisateur (voir exemples).
Appel d'une procédure en sql :
execute procedure [schema.]nom_proc
[(nom_param = val{, nom_param = val})]
On obtient la description d'une procédure par l'ordre
help procedure nom_proc {, nom_proc}
;
Pour retrouver la liste et description de toutes les procédures,
on remplace nom_proc par l'astérisque '*'.
L'ordre de destruction d'une procédure est le suivant :
drop procedure nom_proc ;
La seule autorisation possible sur une procédure est "execute",
et ne peut être donnée que par le propriétaire de la
base sur ses procédures. Ceci permet d'affiner les droits d'accès,
car ils sont indépendants des droits sur les tables (possibilités
de mise à jour à travers une procédure, sans droit
"update" sur une table).
Les procédures sont déclenchées par des règles
ou à l'intérieur de programmes
(C, fortran, ..) ou dans des applications Windows4gl.
III-18-3 Gestion des
règles
L'ordre de création d'une règle est le suivant :
create rule nom_regle
after maj_sql {, maj_sql}
on | from | into nom_table
[referencing [old as ref_ancien]
[new as ref_nouv]]
[where cond_rech]
execute procedure nom_proc
[[nom_param = val {, nom_param = val} ) ]
;
La règle nom_regle va activer l'exécution de la procédure
nom_proc, sur certains ordres de mise à jour sql, "maj_sql", qui
sont soit insert, delete ou update tentés sur
n'importe quelle ligne (colonne pour l'update) de la table nom_table.
La procédure référencée dans la règle
doit exister au moment de création de cette dernière. Le
mot clef referencing a peu d'intérêt, en revanche sa
fonction, implicitement remplie par les mots clefs old et new
est importante. La condition de recherche cond_rech peut vouloir comparer,
lors d'une mise à jour, les valeurs anciennes et nouvelles d'une
colonne ; pour les différencier, elles seront préfixées
par old. et new..
III-18-4 Exemples de
règles et procédures
Voici une procédure qui permettra de vérifier, dans une base
de gestion de personnel, s'il existe bien un corps, classe, et échelon
dans la grille statutaire pour y positionner un agent.
La procédure a trois paramètres d'entrée (corps,
classe, echelon) et deux variables internes check_grille qui ne
peut avoir que la valeur 1 ou 0 dans notre cas (existence unique ou absence
du triplet corps-classe-echelon fourni) et une variable caractère
qui contiendra le message d'erreur fourni à l'utilisateur, s'il
a fourni des données erronées.
On remarquera que les variables locales sont, uniquement à l'intérieur
des ordres sql, précédées d'un ":" , afin de différencier
colonnes de tables et variables locales.
create procedure position_valide
(
corps char(5),
classe integer2,
echelon char(2))
as
declare check_grille integer;
mess varchar(100) not null;
begin
select count(*) into :check_grille
from grille
where corps = :corps and
classe = :classe and
echelon = :echelon;
if check_grille = 0 then
mess = ' saisie sans correspondance avec
la table grille ';
raise error 1 :mess;
return;
endif;
end
Et voici maintenant la règle qui déclenchera la procédure,
lorsque l'on voudra soit insérer un nouvel agent sur une position
donnée, soit faire une mise à jour sur une nouvelle position.
create rule verif_grille
after insert, update from agent
execute procedure postion_valide(
corps = new.corps,
classe = new.classe,
echelon = new.echelon);
On passe à la procédure les valeurs nouvelles proposées
soit à l'insertion, soit en mise à jour, ce qui explique
le mot-clef new.
Voici maintenant un exemple de mise à jour en cascade. Il s'agit
de plusieurs arbres généalogiques sur une population, décrit
de la façon suivante dans une table :
pers(num, nom, est_enfant_de, rang)
La colonne est_enfant_de contient le numéro (num)
du parent, rang est une colonne numérique non renseignée
qui nous servira au classement.
Notre problème est de trouver au sein de la population, aussi
facilement que possible, tous les descendants d'une personne donnée,
avec leur rang de descendance. Ceci sera possible en une seule requête,
mais pour le moins étonnante, car nous passerons par une mise à
jour (update) du rang de la personne dont on cherche la descendance, pour
obtenir automatiquement le classement souhaité.
Nous allons créer un ensemble procédure-règle,
qui, lorsque l'on mettra à jour la colonne rang avec la valeur
1 pour un individu donné, rangera ses descendants en augmentant
rang
de 1 à chaque génération (2 pour les enfants, 3 pour
les petits-enfants,..), rang devenant null (manquant) pour
tous les autres individus (ascendants ou autres familles). Une seule mise
à jour (rang = 1 pour un numéro donné) va déclencher
une cascade de mises à jour sur la table pers.
create procedure maj_pers_rang(
num integer1, bid integer1)
as
begin
/* version faisant une mise a null pour
chaque demande
si maj volontaire de rang à 1 */
if (:bid = 1) then
update pers
set rang = null
where num != :num;
endif;
update pers
set rang = :bid + 1
where est_enfant_de = :num;
end ;
create rule cherche_descendance
after update (rang) of
pers
where new.rang is not null
execute procedure maj_pers_rang(
num = new.num , bid = new.rang);
Voici les résultats de deux mises à jour et consultation
de la table pers :
/* recherche de la descendance du numéro
7 */
1> update pers set rang = 1 where
num = 7
(1 row)
2> select * from pers
3> where rang is not null order by 4
num |
nom |
est_enfant_de |
rang |
7 |
Muriel |
3 |
1 |
14 |
François |
7 |
2 |
15 |
Maurice |
7 |
2 |
16 |
Gerard |
15 |
3 |
18 |
Georgette |
16 |
4 |
19 |
Germaine |
16 |
4 |
20 |
Loic |
16 |
4 |
(7 rows)
/* recherche de la descendance du numéro
15 */
2> update pers set rang = 1 where num = 15
(1 row)
2> select * from pers
3> where rang is not null order by 4
num |
nom |
est_enfant_de |
rang |
15 |
Maurice |
7 |
1 |
16 |
Gerard |
15 |
2 |
18 |
Georgette |
16 |
3 |
19 |
Germaine |
16 |
3 |
20 |
Loic |
16 |
3 |
III-19 Autres types de
données : les objets spatiaux
Avec l'extension objet de OpenIngres, on dispose d'une bibliothèque
de nouveaux types de données, les objets spatiaux, qui comprennent
le point (point), la boîte (box), le segment de droite
(lseg), la ligne et la ligne longue (line et long line),
le polygone et le polygone long (polygon et long polygon),
le cercle (circle).
Ces types peuvent être utilisés dans les définitions
d'attributs de tables. Il leur correspond des opérateurs et des
fonctions qui permettent de les manipuler et de faire des opérations
de type spatial.
III-19-1 Le type point
"point"
Il consiste en 2 valeurs de coordonnées x et y, chacune
étant du type float8.
Exemple d'utilisation :
création d'une table :
create table point_table( id
char(2), obj point);
insertion dans une table :
insert into point_table values
('AA', '(1,1)');
insert into point_table values
('BB', '(0.0,12.37)');
insert into point_table values
('CC', '(1234,-54321)');
III-19-2 Le type boîte
"box"
Une boîte est un rectangle dont les côtés
sont parallèles aux axes du système de coordonnées.
Elle est définie par deux points qui sont le point inférieur
gauche et le point supérieur droit, par exemple ((1, 2.25), (5,
6,5)).
Exemple d'utilisation :
création d'une table :
create table box_table ( id
char(2), obj box);
insertion dans une table :
insert into box_table values('A',
'((0,0), (1,1))');
insert into box_table values ('B',
'((-10,0), (10,1))');
insert into box_table values ('C',
'((110,10),(211,21))');
III-19-3 Le type segment
"lseg"
Un segment est défini par deux éléments
: le point début et le point fin, par exemple
((1, 2), (3.45, -4.0)).
Exemple d'utilisation :
création d'une table :
create table lseg_table ( id char(1),
obj lseg);
insertion dans une table :
insert into lseg_table values('A',
'((0, 0), (1, 2))');
insert into lseg_table values
('B', '((-120, 0),(120,1))');
insert into lseg_table values
('C', '((11.3,10), (21.1, 2.1))');
III-19-4 Le type ligne
"line"
Une ligne est définie par deux parties : le nombre
de points qu'elle comporte et le tableau des points. Pour définir
un attribut de type line, on donnera sa dimension. Pour créer les
données d'une ligne, on donnera les coordonnées de ses points.
Remarque : une ligne ne peut avoir plus de 124 points (taille maximale
d'un tuple).
Exemple d'utilisation :
création d'une table :
create table line_table ( id
char(2), obj line (3));
insertion dans une table :
insert into line_table values
('L1', '((0, 0), (1,1), (2, 2))');
insert into line_table values
('L2', '((0.5, 0.5),(1.5,1.5), (2, 2))');
insert into line_table values
('L3', '((-0.4, -0.3),(1,1), (2, 2))');
III-19-5 Le type ligne
longue "long line"
Une ligne longue permet d'étendre la taille maximale d'une ligne
à 100 million de points environ, correspondant à un encombrement
de 2Goctets.
III-19-6 Le type polygone
"polygon"
Un polygone est défini par deux parties, comme le
type line : le nombre de points qu'il comporte et le tableau des points.
Mais les points doivent respecter la fermeture du polygone. Pour définir
un attribut de type polygon, on donnera sa dimension. Pour créer
les données d'un polygone, on donnera les coordonnées de
ses points.
Remarque : un polygone ne peut avoir plus de 124 points (taille maximale
d'un tuple).
Exemple d'utilisation :
création d'une table :
create table polygon_table ( id
char(2),
obj polygon (4));
insertion dans une table :
insert into polygon_table
values
('P1', '((0, 0), (1,1),(2, 2), (0, 0))');
III-19-7 Le type polygone
long "long polygon"
Un polygone long permet d'étendre la taille maximale
d'un polygone à 100 million de points environ, correspondant à
un encombrement de 2Goctets.
III-19-8 Le type cercle
"circle"
Un cercle est défini par deux éléments
: le point centre du cercle et le rayon, le rayon étant de type
float.
Exemple d'utilisation :
création d'une table :
create table circle_table ( id
char(2),
obj circle);
insertion dans une table :
insert into circle_table
values
('C1', '((0, 0), 1)');
insert into circle_table values
('C2', '((1, 1), 10)');
insert into circle_table values
('C3', '((0, 0), 20)');
III-19-9 Tableau des
formats des types spatiaux
Nom |
Format de stockage |
Etendue |
point |
2 flottants de 8 octets |
-1.0e+38 à 1.0 e+38
précision de 16 chiffres |
lseg |
2 points |
-1.0e38 à 1.0 e38
précision de 16 chiffres |
line |
1 entier
1 tableau de points |
2 à 124
-1.0e+38 à 1.0 e+38
précision de 16 chiffres |
box |
2 points |
-1.0e+38 à 1.0 e+38
précision de 16 chiffres |
polygon |
1 entier |
3 à 124
-1.0e+38 à 1.0 e+38
précision de 16 chiffres |
circle |
1 point
1 flottant |
-1.0e3+8 à 1.0 e+38
précision de 16 chiffres
même que float
doit être > 0.0 |
III-19-10 Les opérateurs
spatiaux disponibles
-
les opérateurs de comparaison d'égalité = et
<>
ils s'appliquent à 2 attributs de même type et comparent
leur représentation interne;
ex : comparaison de 2 segments
((1, 2), (3, 4)) <> ((3, 4), (1, 2))
donnera vrai
-
les opérateurs spatiaux binaires : inside et intersects
inside (objet1, objet2)
rend la valeur 1 si l'objet1 est contenu dans l'objet2
tableau des combinaisons de types valides pour l'opérateur inside
:
|
point
|
box |
lseg |
line et
long line |
polygon et
long polygon |
circle |
point |
non
|
oui |
non |
non |
oui |
oui |
box |
non
|
oui |
non |
non |
oui |
oui |
lseg |
non
|
oui |
non |
non |
oui |
oui |
line et
long line |
non
|
oui |
non |
non |
oui |
oui |
polygon et
long polygon |
non
|
oui |
non |
non |
oui |
oui |
circle |
non
|
oui |
non |
non |
oui |
oui |
intersects (objet1, objet2)
rend la valeur 1 si l'objet1 intersecte l'objet2; tous les types d'objets
sont permis.
III-19-11 Les fonctions
disponibles sur les attributs de types spatiaux
Il y a trois types de fonctions :
-
les fonctions spatiales, telles que la fonction area, perimeter,
etc.
-
les fonctions de conversions spatiales
-
les fonctions spatiales de conversions de types
-
les fonctions spatiales
area |
calcule la surface d'une boîte, d'un cercle,
d'un
polygone |
length |
calcule la longueur d'une ligne, d'un segment |
perimeter |
calcule le périmètre d'une boîte,
d'un cercle, d'un polygone |
distance |
calcule la distance entre 2 points |
-
les fonctions de conversions spatiales
elles acceptent un type spatial et rendent, soit une valeur de type
point, soit une valeur de type flottante (double) correspondant à
la coordonnée x ou y:
point_x |
rend la coordonnée x d'un point |
point_y |
rend la coordonnée y d'un point |
box_ll |
rend le point inférieur gauche |
box_ur |
rend le point supérieur droit |
line |
convertit un segment en ligne |
bbox |
rend la boîte entourant l'objet |
-
les fonctions spatiales de conversions de types, décrites par le
tableau suivant :
Nom |
Opérande |
Type du résultat |
Description |
bbox |
lseg
line
long line
polygon
long polygon
circle |
box |
convertit l'opérande en une représentation
interne de box. Les limites de la boîte sont définies par
la paire de valeurs x, y minimales et maximales trouvées dans le
type converti. |
Box |
char
varchar |
box |
convertit une chaîne de type char ou varchar
en une représentation interne de box. |
Char |
point
lseg
box
line
polygon
circle |
char |
rend une représentation en chaîne
de caractères de l'opérande |
circle |
char
varchar |
circle |
convertit une chaîne de type char ou varchar
en une représentation interne de circle. |
Line |
char
varchar |
line |
convertit une chaîne de type char ou varchar
en une représentation interne de line. |
Long line |
char
varchar |
long line |
convertit une chaîne de type char ou varchar
en une représentation interne de long line. |
Polygon |
char
varchar |
polygon |
convertit une chaîne de type char ou varchar
en une représentation interne de polygon. |
Long polygon |
char
varchar |
long polygon |
convertit une chaîne de type char ou varchar
en une représentation interne de long polygon. |
Lseg |
char
varchar |
lseg |
convertit une chaîne de type char ou varchar
en une représentation interne de lseg. |
Point |
char
varchar |
point |
convertit une chaîne de type char ou varchar
en une représentation interne de point. |
Varchar |
point
lseg
box
line
polygon
circle |
varchar |
rend une représentation en chaîne
de caractères de l'opérande (comme la fonction char). |
|