Py学习  »  Schwern  »  全部回复
回复总数  4
4 年前
回复了 Schwern 创建的主题 » MySQL如何使用check?

Other answers covered using the check constraints .

然而,如果 总是 要以“E”开头,您需要存储“E”吗?你能存储整数,然后再加上E吗?整数主键更简单、更快、更小、更健壮。

使用 generated column 提供带有E的ID。

create table Employee (
  -- No check required, it's an integer by definition.
  -- Takes less storage to store and index.
  ID integer primary key,

  -- A generated virtual column (takes no storage space)
  EmployeeID varchar(255) as (concat('E', id)) virtual
);

insert into Employee (id) values (1), (23), (456);

select * from Employee;

ID      EmployeeID
1       E1
23      E23
456     E456

select * from Employee where EmployeeID = 'E456';

ID      EmployeeID
456     E456

Try it .

6 年前
回复了 Schwern 创建的主题 » 只有当值存在时,MySQL字符串串接

使用 concat_ws . 它将自动跳过空值。

mysql> select concat_ws('\\', 'foo', 'bar', null, 'baz');
+--------------------------------------------+
| concat_ws('\\', 'foo', 'bar', null, 'baz') |
+--------------------------------------------+
| foo\bar\baz                                |
+--------------------------------------------+

但是它不会跳过空白。

mysql> select concat_ws('\\', 'foo', 'bar', '', 'baz');
+------------------------------------------+
| concat_ws('\\', 'foo', 'bar', '', 'baz') |
+------------------------------------------+
| foo\bar\\baz                             |
+------------------------------------------+

好的模式不会处理空值和 '' 相同的。但有时你别无选择。在这种情况下使用 nullif 把空白变成空白。

mysql> set @var = '';
mysql> select concat_ws('\\', 'foo', 'bar', nullif(@var, ''), 'baz');
+--------------------------------------------------------+
| concat_ws('\\', 'foo', 'bar', nullif(@var, ''), 'baz') |
+--------------------------------------------------------+
| foo\bar\baz                                            |
+--------------------------------------------------------+

你可能想把这些都变成 stored procedure .

6 年前
回复了 Schwern 创建的主题 » 如何将数据插入到MySQL中的动态表中?

如果发现自己拥有多个具有相同列的表,那么可能会有一个设计不良的模式。对于一个设计良好的模式,您所要求的不是必需的。我鼓励你问一个关于如何设计你的模式来避免你的问题的另一个问题。


将未筛选的字符串连接在一起容易受到 SQL Injection attack 是的。相反,只要有可能,使用绑定参数并将值传递到。这样可以确保它们被正确地转义和引用,不会被意外或恶意地曲解。

SET @q = 'INSERT INTO `' , @tableName, '` VALUES(?,?,?,?,?,?)';
PREPARE stmt FROM @q;
EXECUTE stmt USING @NName, @APName, @AMName, @NomName, @DNIName, @DirectName

这也解决了你的其他问题,不是所有的事情都是一串。

CALL insert_data ('table_x', 'NULL', 'A', 'B', 'C', 'D', 'E ')
                              ^^^^

绑定参数将保留非字符串的类型,如整数和空值。我也会注意到 N 是一个整数,但您使用它作为通常表示字符串的名称。所以这可能是个问题。


关于那个讨厌的表名。我们不能把它作为一个绑定参数来传递。你要确保它不能跳出引号,所以必须转义。你也不希望任何人能跳转到另一个数据库,所以 . 也必须逃走。或者更好, raise an error 是的。我们不能用 quote() 因为这是针对具有不同引用规则的列值的。我们得自己写。

DELIMITER $$
drop procedure if exists check_table_name;
CREATE PROCEDURE check_table_name (
    table_name varchar(255)
)
begin
    if( locate("`", table_name) ) then
        signal sqlstate '45000'
            set message_text = 'illegal ` in table name';
    elseif( locate(".", table_name) ) then
        signal sqlstate '45000'
            set message_text = 'illegal . in table name';
    end if;
end $$
DELIMITER ;

现在我们在使用表名之前调用它。

call check_table_name(@tableName);
SET @q = concat('INSERT INTO `' , @tableName, '` VALUES(?,?,?,?,?,?)');
PREPARE stmt FROM @q;
EXECUTE stmt USING @NName, @APName, @AMName, @NomName, @DNIName, @DirecName;
DEALLOCATE PREPARE stmt;

如果是淘气,我们会出错的。

mysql> call insertar_datos("foo`haha, I broke your quoting`bar", 23, 'A', 'B', 'C', 'D', 'E ');
ERROR 1644 (45000): illegal ` in table name

但是再一次 我强烈反对这种做法 是的。任何时候,你把字符串串在一起做SQL语句时,你就有漏洞和安全缺陷的风险。我不相信 check_table_name 把所有的问题都解释清楚了。

如果必须采用这种方法,请考虑使用一组固定的允许名称。

if name in ("foo", "bar", "baz", "table_x") then
    set @tableName = name;
else
    signal sqlstate '45000'
        set message_text = 'unknown name';
end if;

我建议您考虑重新设计您的模式。

如果您使用的是服务器端代码,请设置环境变量并使用它。

如果你使用的是Github页面, you can't host a server-side app .

GitHub页面是一种静态网站托管服务,旨在直接从GitHub存储库托管您的个人、组织或项目页面。

Github页面是一个静态的站点托管服务,不支持诸如php、ruby或python之类的服务器端代码。

它只适用于静态文件:html、css、javascript。这些将在浏览器中执行。没有要设置的环境变量。没有地方向用户隐藏秘密。

相反,将其构建为 OAuth App . OAuth允许用户授权您的网站使用其帐户访问GitHub API。这就是Github自己的graphqlAPI导出器的工作原理。