PHP Mysql-在Select语句中使用变量作为列名

PHP Mysql-在Select语句中使用变量作为列名,php,mysql,sql-server,database,Php,Mysql,Sql Server,Database,我的表中有月份名称作为列名,如一月、二月、三月等。 在我的表单中,用户需要从下拉列表中选择一个月,我从中选择用户的选择 作为$month\u名称。我想查看$month_name中的数据,它不是0.00 当我回显$month_名称时,我得到:一月或二月等 我在select语句中使用了$month_name,但不起作用: 第一次尝试不工作: $sql = "SELECT * FROM bookoff_monthly WHERE '.$month_name.' <> 0.00 AND ye

我的表中有月份名称作为列名,如一月、二月、三月等。 在我的表单中,用户需要从下拉列表中选择一个月,我从中选择用户的选择 作为$month\u名称。我想查看$month_name中的数据,它不是0.00

当我回显$month_名称时,我得到:一月或二月等

我在select语句中使用了$month_name,但不起作用: 第一次尝试不工作:

$sql = "SELECT * FROM bookoff_monthly WHERE '.$month_name.' <> 0.00 AND year='$year' ";
$sql = "SELECT * FROM bookoff_monthly WHERE $month_name <> 0.00 AND year='$year' ";
第二,尝试不工作:

$sql = "SELECT * FROM bookoff_monthly WHERE '.$month_name.' <> 0.00 AND year='$year' ";
$sql = "SELECT * FROM bookoff_monthly WHERE $month_name <> 0.00 AND year='$year' ";
**但以下方法可行,但这不是我想要的:


<>这是我认为适当逃脱的:

$sql = "SELECT * FROM bookoff_monthly WHERE `".$month_name."` <> 0.00 AND year='".$year."' ";
假设您的变量的格式正确,那么这应该是可行的


编辑:正如VMai所说,由于您使用的是3个字母的月份名称,因此在查询中不可避免地使用DEC或DEC,这是MySQL中的一个保留字,因此您必须用反勾号转义名称,否则查询将被误解。

$sql='SELECT*FROM bookoff\u monthly WHERE.$month\u name.'0.00和year='.$year.'

1的问题是您试图混合使用单引号和双引号。假设$month_name=jan,这将为您提供:

SELECT * FROM bookoff_monthly WHERE '.jan.' <> 0.00 AND year='$year'
由于“.jan.”不等于0.00,因此找不到任何记录

你的第二个在我看来应该有用。您可以尝试打印生成的字符串,以查看它提供了什么。也许您在月份名称或其他内容中有您不期望的其他字符

但在任何情况下,这只是要求SQL注入攻击。例如,黑客可以伪造你的输入表单,将jan=1+1=2;每月从bookoff_中删除,其中1.00,现在它将删除给定年份的所有内容

另外,任何让您在运行中生成字段名的设计都应该立即受到质疑


正确的方法是建立多对多的关系,每个月有一个记录。与创建表bookoff\u month bookoff\u id int、month char3、amount decimal7,2类似。然后,您的查询变成select*from bookoff\U MOUNTRY join bookoff\U MOUNT on bookoff\U MOUNTRY.bookoff\U id=bookoff\U MOUNTRY.bookoff\U id,其中MOUNTRY=?年份=?并用一个准备好的语句填充它们,或者至少将参数包装在一个进行适当转义的函数中。

您可以添加转义标识符,在这种情况下是必须的,因为DEC列将打断未转义的查询。原因:DEC是MySQL中的一个错误$年份可以按原样使用,但最好使用参数化的准备语句。请注意,不能使用参数作为标识符。这是一个很好的观点!我总是将列名和表名包装在后面的记号中,这也是正确的,但不在本问题的范围内。注意,引用的仍然没有转义——查询仍然容易受到攻击。仅当$month_name被引用为标识符,$year被引用为文本时,此操作才有效。因为OP根本没有执行任何SQL保护,所以这确实应该在答案中加以说明。同意回执。不同意保留双引号。我会一直呆在引号里,因为变量是在双引号中解析的,而且没有连接符更容易查看/读取*这个答案虽然可行,但形式极其糟糕。嵌入到查询中的标识符和文本都不受注入保护。