绑定参数的名称

huangapple go评论60阅读模式
英文:

Bind the name of a parameter

问题

Doctrine中,是否可以绑定参数的名称(与绑定参数的相反)?

为什么我需要这个

有一张表有7个布尔列,分别对应一周的每一天:mondaytuesday等(这些对应于由GTFS定义的calendar实体的结构,https://gtfs.org/schedule/reference/#calendartxt)。

给定一周的某一天(比如monday),我想要获取所有在星期一可用的行,即:

$statement = $this
    ->getEntityManager()
    ->getConnection()
    ->prepare('
        SELECT id
        FROM calendar
        WHERE monday = 1
    ');

总的来说,我想要能够在查询中提供一天的名称,我可以通过以下简单实现:

->prepare("
    SELECT id
    FROM calendar
    WHERE $dayName = 1
");

我想知道是否可以使用参数绑定来绑定参数的名称,类似于:

$statement = $this
    ->getEntityManager()
    ->getConnection()
    ->prepare('
        SELECT id
        FROM calendar
        WHERE :dayName = 1
    ');

$statement->bindValue('dayName', $dayName);

但这并不起作用,请见下文。

我尝试过的方法

#1

WHERE :dayName = 1

转换为以下SQL查询:

SELECT calendar.id
FROM calendar
WHERE 'monday' = 1

由于该条件永远不会成立,返回一个空集,[]

#2

WHERE `:dayName` = 1
SELECT calendar.id
FROM calendar
WHERE `'monday'` = 1

列未找到:1054 where子句中的未知列'‘monday’'

#3

WHERE ":dayName" = 1
# 没有查询

无效的参数编号:绑定变量的数量与令牌的数量不匹配

英文:

In Doctrine, is it possible to bind the name of a parameter
(contrary to binding the value of a parameter)?

Why I need it

There is a table having 7 boolean columns, one for each day of the week: monday, tuesday, etc. (these correspond to the structure of the calendar entity defined by GTFS, https://gtfs.org/schedule/reference/#calendartxt).

Given a day of the week (say, monday), I want to get all rows, which are available on Mondays, i.e.:

$statement = $this
    ->getEntityManager()
    ->getConnection()
    ->prepare('
        SELECT id
        FROM calendar
        WHERE monday = 1
    ');

Generally, I want to be able to supply the name of a day in that query, which I can do simply by:

->prepare("
    SELECT id
    FROM calendar
    WHERE $dayName = 1
");

I wonder whether it's possible to use the parameter binding for the names of parameters, i.e. something like

$statement = $this
    ->getEntityManager()
    ->getConnection()
    ->prepare('
        SELECT id
        FROM calendar
        WHERE :dayName = 1
    ');

$statement->bindValue('dayName', $dayName);

which does not work, see below.

What I tried

#1

WHERE :dayName = 1

which translates to the following SQL query:

SELECT calendar.id
FROM calendar
WHERE 'monday' = 1

and, because that condition is never true, returns an empty set, [].

#2

WHERE `:dayName` = 1
SELECT calendar.id
FROM calendar
WHERE `'monday'` = 1

Column not found: 1054 Unknown column ''monday'' in 'where clause'

#3

WHERE ":dayName" = 1
# no query

Invalid parameter number: number of bound variables does not match number of tokens

答案1

得分: 2

这当然是不可能的。

在语句中,占位符可用作参数标记,以指示在执行查询时数据值将绑定到哪里。参数标记不应包含在引号内,即使您打算将它们绑定到字符串值。参数标记只能用于表达式应出现的地方,不能用于SQL关键字、标识符等。

简而言之:您只能将参数标记用于文字(字符串、数字等)。

如果您无法更改数据库设计,我建议使用另一个带有简单位检查的SQL语句:

prepare("select id, (monday + 
                     tuesday * 2 + 
                     wednesday * 4 + 
                     thursday * 8 + 
                     friday * 16 + 
                     saturday * 32 + sunday *64) as day
from calendar having (day) & (1 << :daynumber)")

现在,您可以通过绑定daynumber(monday=0,tuesday=1,.. sunday=6)来简单地检查特定工作日是否可用。

英文:

This is of course not possible.

Within the statement, placeholders can be used as parameter markers to indicate where data values are to be bound to the query later when you execute it. The parameter markers should not be enclosed within quotes, even if you intend to bind them to string values. Parameter markers can be used only where expressions should appear, not for SQL keywords, identifiers, and so forth.

In short: you can use parameter markers for literals (string, numbers, ..) only

If you can't change your database design I would recommend using another SQL statement with a simple bit check:

prepare(&quot;select id, (monday + 
                     tuesday * 2 + 
                     wednesday * 4 + 
                     thursday * 8 + 
                     friday * 16 + 
                     saturday * 32 + sunday *64) as day
from calendar having (day) &amp; (1 &lt;&lt; :daynumber)&quot;)

Now you can simply check if a service is available on a specific weekday, by binding the daynumber (monday=0, tuesday=1, .. sunday=6).

huangapple
  • 本文由 发表于 2023年2月18日 20:13:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/75493257.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定