Bonjour,
Comment pouvons-nous implĂ©menter une jointure de table sur deux schĂ©mas diffĂ©rents mais sur la mĂȘme base de donnĂ©es.
Techniquement, les schĂ©mas ne sont que la sĂ©paration logique des tables au sein de la mĂȘme base de donnĂ©es, donc lors de l'Ă©criture d'une requĂȘte SQL, tout ce dont nous avons besoin est de les prĂ©fixer avec le nom du schĂ©ma.
Par example,
select *
from user_schema.users as users
inner join account_schema.accounts as accounts
on users.users.id = accounts.user_id
Je pourrais probablement écrire ci-dessous kenx.js. Est-ce que ça a l'air bien ?
knex.from('user_schema.users as users').innerJoin('account_schema.accounts as accounts',
'users.id', 'accounts.user_id')
Mais ensuite j'ai vu. Option withSchema
avec knex.js Quel est l'avantage d'utiliser cette option au lieu de préfixer le nom de la table avec schema. Comment puis-je utiliser l'option .withSchema
pour joindre des tables de jointure à partir de deux schémas différents ?
Knex.js Documentation
------------------------
.withSchema([schemaName])
Specifies the schema to be used as prefix of table name.
knex.withSchema('public').select('*').from('users')
Outputs:
select * from `public`.`users`
une solution pour celui-ci ?
Le document indique la syntaxe de l'identificateur, c'est-Ă -dire le nom de la table, le nom de la colonne, n'a pas de place pour sĂ©lectionner le schĂ©ma, donc si vous faites schemaName.tableName, la requĂȘte peut ĂȘtre mal rendue.
Il a suggéré d'utiliser .withSchema('schemaName')
la place.
Mais j'ai trouvé que .withSchema
ne fonctionnait que dans un seul schéma dans tout le bloc de construction.
Jusqu'à présent, j'ai les sollutines temporaires suivantes :
N'utilisez pas du tout .withSchema
dans une requĂȘte de speasure, incluez le nom du schĂ©ma dans la chaĂźne du nom de la table.
Ceci contre le document.
Utiliser une sous-requĂȘte avec .withSchema
{
let rows = await knex.withSchema("sandbox1")
.select('first_name', 'last_name', 'phone', 'site', "sites.name as sname")
.from('users')
.leftJoin(
knex.withSchema('public')
.table('sites')
.select()
.as("sites"),
"sites.id",
"users.site")
console.log(rows)
}
De cette façon, vous devez utiliser .as
dans la sous-requĂȘte.
.joinRaw()
{
let queryBuilder = knex.withSchema("sandbox1")
.select('first_name', 'last_name', 'phone', 'site', "sites.name as sname")
.from('users')
.joinRaw("left join public.sites as sites ON sites.id = users.site", [])
let sql = queryBuilder.toSQL().toNative()
let rows = await queryBuilder
console.log((sql))
console.log(rows)
}
.raw()
{
let { rows ,rowCount } = await knex
.raw('SELECT users.first_name, users.last_name, users.phone, users.site, sites.name as sname FROM sandbox1.users, public.sites WHERE sites.id = users.site;');
console.log(rows)
}
Cela a moins d'avantages Ă utiliser knex.
La derniĂšre puissance.
Ajout d'un détail supplémentaire à la réponse de @codinggirl :
En utilisant joinRaw() , vous pouvez lier les paramĂštres. Ce qui gĂ©nĂšre une requĂȘte avec une syntaxe identique partout dans la requĂȘte.
{
const queryBuilder = knex.withSchema("sandbox1")
.select('first_name', 'last_name', 'phone', 'site', "sites.name as sname")
.from('users')
.joinRaw("left join ?? ON ?? = ??", ["public.sites", "sites.id", "users.site"])
const sql = queryBuilder.toString()
console.log(sql)
}
Remarque : Liaisons positionnelles ? sont interprétés comme des valeurs et ?? sont interprétés comme des identifiants.
Sortie avec liaisons sur PGÂ :
sélectionnez "first_name", "last_name", "phone", "site", "sites"."name" as "sname" from "sandbox1"."users" left join "public"."sites" ON "sites". "id" = "utilisateurs".."site"
Sortie avec liaisons sur MSSQLÂ :
sélectionnez [first_name], [last_name], [phone], [site], [sites].[name] as [sname] from [sandbox1].[users] left join [public].[sites] ON [sites]. [id] = [utilisateurs].[site]
Pendant ce temps, sans liaison, cela générerait toujours :
sélectionnez "first_name", "last_name", "phone", "site", "sites"."name" as "sname" from "sandbox1"."users" left join public.sites ON sites.id = users.site
Commentaire le plus utile
Le document indique la syntaxe de l'identificateur, c'est-Ă -dire le nom de la table, le nom de la colonne, n'a pas de place pour sĂ©lectionner le schĂ©ma, donc si vous faites schemaName.tableName, la requĂȘte peut ĂȘtre mal rendue.
Il a suggéré d'utiliser
.withSchema('schemaName')
la place.Mais j'ai trouvé que
.withSchema
ne fonctionnait que dans un seul schéma dans tout le bloc de construction.Jusqu'à présent, j'ai les sollutines temporaires suivantes :
N'utilisez pas du tout
.withSchema
dans une requĂȘte de speasure, incluez le nom du schĂ©ma dans la chaĂźne du nom de la table.Ceci contre le document.
Utiliser une sous-requĂȘte avec
.withSchema
De cette façon, vous devez utiliser
.as
dans la sous-requĂȘte..joinRaw()
.raw()
Cela a moins d'avantages Ă utiliser knex.
La derniĂšre puissance.