Knex: 跨两个不同模式连接两个表(一个数据库)

创建于 2016-07-23  ·  3评论  ·  资料来源: knex/knex

你好,
我们如何跨两个不同的模式但相同的数据库实现表连接。
从技术上讲,模式只是同一数据库中表的逻辑分离,因此在编写 SQL 查询时,我们只需要在它们前面加上模式名称即可。
例如,

select * 
from user_schema.users as users
inner join account_schema.accounts  as accounts
on users.users.id = accounts.user_id

我可能会写在 kenx.js 下面。 那看起来不错吗?

knex.from('user_schema.users as users').innerJoin('account_schema.accounts as accounts', 
'users.id', 'accounts.user_id')

但后来我看到了。 withSchema选项与 knex.js 使用该选项而不是在表名前加上模式有什么好处。 如何使用.withSchema选项连接来自两个不同模式的连接表?

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`

最有用的评论

文档说标识符语法,即表名、列名,没有选择模式的地方,所以如果你在做schemaName.tableName,查询可能会呈现错误。

它建议改用.withSchema('schemaName')

但我发现.withSchema只能在整个构建器块中的一个模式中工作。

到目前为止,我有以下临时解决方案:

  • 不要在 speasure 查询中使用.withSchema ,在表名字符串中包含模式名称。
    这违反了文件。

  • 使用带有.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)
    }

这种方式需要在子查询中使用.as

  • 使用.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)
    }

使用 knex 的好处较少。

  • 使用其他库或 ORM 或驱动程序。

最后的力量。

所有3条评论

这个有什么解决方案吗?

文档说标识符语法,即表名、列名,没有选择模式的地方,所以如果你在做schemaName.tableName,查询可能会呈现错误。

它建议改用.withSchema('schemaName')

但我发现.withSchema只能在整个构建器块中的一个模式中工作。

到目前为止,我有以下临时解决方案:

  • 不要在 speasure 查询中使用.withSchema ,在表名字符串中包含模式名称。
    这违反了文件。

  • 使用带有.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)
    }

这种方式需要在子查询中使用.as

  • 使用.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)
    }

使用 knex 的好处较少。

  • 使用其他库或 ORM 或驱动程序。

最后的力量。

@codinggirl的答案添加更多细节:

使用joinRaw()您可以绑定参数。 它在整个查询中生成具有相同语法的查询。

    {
        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)
    }

注意:位置绑定? 被解释为值和?? 被解释为标识符。

在 PG 上绑定的输出:
从“sandbox1”中选择“first_name”、“last_name”、“phone”、“site”、“sites”。“name”作为“sname”。“users”离开加入“public”。“sites”在“sites”上。 “id”=“用户”。“站点”

输出与 MSSQL 上的绑定:
选择 [first_name], [last_name], [phone], [site], [sites].[name] as [sname] from [sandbox1].[users] left join [public].[sites] ON [sites]。 [id] = [用户].[站点]

同时,如果没有绑定,它总是会生成:
从“sandbox1”中选择“first_name”、“last_name”、“phone”、“site”、“sites”。“name”作为“sname”。“users”离开加入 public.sites ON sites.id = users.site

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

ghost picture ghost  ·  3评论

saurabhghewari picture saurabhghewari  ·  3评论

arconus picture arconus  ·  3评论

tjwebb picture tjwebb  ·  3评论

zettam picture zettam  ·  3评论