使用 MySQL 我可以运行查询:
SHOW CREATE TABLE MyTable;
它将返回指定表的创建表语句。如果您已经创建了一个表,并且想要在另一个数据库上创建同一个表,这将非常有用。
是否可以获得已经存在的行或行集的插入语句?有些表有很多列,如果能够获得一个插入语句将行传输到另一个数据库,而不必写出插入语句,或者无需将数据导出到 CSV 然后导入相同的数据,那就太好了进入另一个数据库。
只是为了澄清一下,我想要的是可以按如下方式工作的东西:
SHOW INSERT Select * FROM MyTable WHERE ID = 10;
并为我返回以下内容:
INSERT INTO MyTable(ID,Col1,Col2,Col3) VALUES (10,'hello world','some value','2010-10-20');
mysql>
提示中的 INSERT 语句的答案。到目前为止还没有。
似乎没有办法从 MySQL 控制台获取 INSERT
语句,但您可以像 Rob 建议的那样使用 mysqldump 获取它们。指定 -t
以省略表创建。
mysqldump -t -u MyUserName -pMyPassword MyDatabase MyTable --where="ID = 10"
在 MySQL Workbench 中,您可以将任何单表查询的结果导出为 INSERT
语句的列表。只需运行查询,然后:
https://i.stack.imgur.com/76Rmz.png
单击结果上方导出/导入附近的软盘,在窗口底部为目标文件命名,为格式选择 SQL INSERT 语句单击保存单击导出
由于您使用 SHOW CREATE TABLE MyTable 生成的 SQL 复制了表,因此您只需执行以下操作即可将数据加载到新表中。
INSERT INTO dest_db.dest_table SELECT * FROM source_db.source_table;
如果您真的想要 INSERT 语句,那么我所知道的唯一方法是使用 mysqldump http://dev.mysql.com/doc/refman/5.1/en/mysqldump.htm。您可以为其提供选项以仅转储特定表的数据,甚至限制行。
我写了一个 php 函数来做到这一点。我需要创建一个插入语句,以防在删除历史表后需要替换记录:
function makeRecoverySQL($table, $id)
{
// get the record
$selectSQL = "SELECT * FROM `" . $table . "` WHERE `id` = " . $id . ';';
$result = mysql_query($selectSQL, $YourDbHandle);
$row = mysql_fetch_assoc($result);
$insertSQL = "INSERT INTO `" . $table . "` SET ";
foreach ($row as $field => $value) {
$insertSQL .= " `" . $field . "` = '" . $value . "', ";
}
$insertSQL = trim($insertSQL, ", ");
return $insertSQL;
}
O' Malley
,则生成的查询将由于单引号不匹配而出现语法错误。如果走这条路线,您至少应该使用 mysql_real_escape_string
。
Laptop Lift 的代码运行良好,但我认为人们可能会喜欢一些东西。
数据库处理程序是一个参数,不是硬编码的。使用了新的mysql api。将 $id 替换为可选的 $where 参数以提高灵活性。使用 real_escape_string 以防有人尝试过进行 sql 注入并避免涉及引号的简单损坏。使用 INSERT table (field...) VALUES (value...)...
语法,以便字段只定义一次,然后列出每行的值(implode 很棒)。因为 Nigel Johnson 指出了这一点,所以我添加了 NULL
处理。
我使用 $array[$key]
是因为我担心它可能会以某种方式改变,但除非出现严重错误,否则无论如何都不应该。
<?php
function show_inserts($mysqli,$table, $where=null) {
$sql="SELECT * FROM `{$table}`".(is_null($where) ? "" : " WHERE ".$where).";";
$result=$mysqli->query($sql);
$fields=array();
foreach ($result->fetch_fields() as $key=>$value) {
$fields[$key]="`{$value->name}`";
}
$values=array();
while ($row=$result->fetch_row()) {
$temp=array();
foreach ($row as $key=>$value) {
$temp[$key]=($value===null ? 'NULL' : "'".$mysqli->real_escape_string($value)."'");
}
$values[]="(".implode(",",$temp).")";
}
$num=$result->num_rows;
return "INSERT `{$table}` (".implode(",",$fields).") VALUES \n".implode(",\n",$values).";";
}
?>
INSERT INTO {$tables}
上缺少的 INTO
,但没有处理表中的空值。
INTO
完全是 optional。我添加了对空值的处理。
在 PHPMyAdmin 中,您可以:
单击要知道其插入语句SQL的行上的复制:
https://i.stack.imgur.com/BlrgT.png
单击预览 SQL:
https://i.stack.imgur.com/HeUjS.png
您将获得生成它的已创建插入语句
如果您选择它们并单击表格底部的复制,然后单击预览 SQl,则可以一次将其应用于多行
https://i.stack.imgur.com/h6nNE.png
下面的命令将转储到终端,而 mysqldump 不会在 INSERT 周围输出所有额外的东西。这允许从终端复制而不写入文件。如果环境限制写入新文件,这很有用。
mysqldump -u MyUserName -pMyPassword MyDatabase MyTable --where="ID = 10" --compact --no-create-info --complete-insert --quick
使用 mysqldump --help
我发现了以下选项。
-q, --quick 不缓冲查询,直接转储到标准输出。 (默认为 on;使用 --skip-quick 禁用。) -t, --no-create-info 不要写表创建信息。 -c, --complete-insert 使用完整的插入语句。 --compact 提供较少详细的输出(对调试很有用)。禁用结构注释和页眉/页脚结构。启用选项 --skip-add-drop-table --skip-add-locks --skip-comments --skip-disable-keys --skip-set-charset。
在 MySQL 工作台中执行以下操作:
单击服务器 > 数据导出 在对象选择选项卡中选择所需的模式。接下来,使用模式右侧的列表框选择所需的表。选择文件位置以导出脚本。单击完成。导航到新创建的文件并复制插入语句。
如果您想为您的表获取“插入语句”,您可以尝试以下代码。
SELECT
CONCAT(
GROUP_CONCAT(
CONCAT(
'INSERT INTO `your_table` (`field_1`, `field_2`, `...`, `field_n`) VALUES ("',
`field_1`,
'", "',
`field_2`,
'", "',
`...`,
'", "',
`field_n`,
'")'
) SEPARATOR ';\n'
), ';'
) as `QUERY`
FROM `your_table`;
结果,您将拥有 insers 语句:
插入 your_table
(field_1
, field_2
, ...
, field_n
) 值 (value_11, value_12, ... , value_1n);
插入 your_table
(field_1
, field_2
, ...
, field_n
) 值 (value_21, value_22, ... , value_2n);
/.................................................. ..../
插入 your_table
(field_1
, field_2
, ...
, field_n
) 值 (value_m1, value_m2, ... , value_mn);
, 其中 m - your_table 中的记录数
您可以使用 Sequel pro 来执行此操作,对于获得的结果,可以选择“获取为插入语句”
有一个非常简单和有用的解决方案可以创建一个 INSERT 语句进行编辑,而无需使用复制和粘贴(剪贴板)导出 SQL:
在 MySQL Workbench 的查询结果窗口中选择行,可能甚至几行。即使该行包含的数据与我想在脚本中插入的数据不同,或者目标是使用 ? 创建一个准备好的语句,我也会使用它。占位符。
现在将剪贴板中的复制行粘贴到同一个表中(查询结果列表是工作台中的编辑器)到最后一个空闲行。
按“应用”并打开一个窗口,显示 INSERT 语句 - 不要执行
将 SQL 从窗口复制到剪贴板
取消执行,因此不会更改数据库,而是将 SQL 保留在剪贴板中。
将 SQL 粘贴到您想要的任何位置并根据需要进行编辑,例如插入?占位符
您可以使用下面的代码创建一个 SP - 它也支持 NULLS。
select 'my_table_name' into @tableName;
/*find column names*/
select GROUP_CONCAT(column_name SEPARATOR ', ') from information_schema.COLUMNS
where table_schema =DATABASE()
and table_name = @tableName
group by table_name
into @columns
;
/*wrap with IFNULL*/
select replace(@columns,',',',IFNULL(') into @selectColumns;
select replace(@selectColumns,',IFNULL(',',\'~NULL~\'),IFNULL(') into @selectColumns;
select concat('IFNULL(',@selectColumns,',\'~NULL~\')') into @selectColumns;
/*RETRIEVE COLUMN DATA FIELDS BY PK*/
SELECT
CONCAT(
'SELECT CONCAT_WS(','''\'\',\'\''',' ,
@selectColumns,
') AS all_columns FROM ',@tableName, ' where id = 5 into @values;'
)
INTO @sql;
PREPARE stmt FROM @sql;
EXECUTE stmt;
/*Create Insert Statement*/
select CONCAT('insert into ',@tableName,' (' , @columns ,') values (\'',@values,'\')') into @prepared;
/*UNWRAP NULLS*/
select replace(@prepared,'\'~NULL~\'','NULL') as statement;
对于 HeidiSQL 用户:
如果您使用 HeidiSQL,您可以选择您希望获取插入语句的行。然后右键单击>导出网格行>为“输出目标”选择“复制到剪贴板”,为“行选择”选择“选择”,这样您就不会导出其他行,为“输出格式”选择“SQL INSERT”>单击确定。
https://i.stack.imgur.com/VT7ZF.png
插入语句将在您的剪贴板中。
如果您使用 phpMyAdmin(在 5.x 版上测试):
单击您想要插入语句的行旁边的“编辑”按钮,然后在操作按钮旁边的底部选择“显示插入查询”并按“开始”。
使用 PDO,您可以这样做。
$stmt = DB::getDB()->query("SELECT * FROM sometable", array());
$array = $stmt->fetchAll(PDO::FETCH_ASSOC);
$fields = array_keys($array[0]);
$statement = "INSERT INTO user_profiles_copy (".implode(",",$fields).") VALUES ";
$statement_values = null;
foreach ($array as $key => $post) {
if(isset($statement_values)) {
$statement_values .= ", \n";
}
$values = array_values($post);
foreach($values as $index => $value) {
$quoted = str_replace("'","\'",str_replace('"','\"', $value));
$values[$index] = (!isset($value) ? 'NULL' : "'" . $quoted."'") ;
}
$statement_values .= "(".implode(',',$values).")";
}
$statement .= $statement_values . ";";
echo $statement;
我认为笔记本电脑升降机提供的答案是最好的......但由于没有人建议我使用的方法,我想我应该插话。我大部分时间都使用 phpMyAdmin 来设置和管理我的数据库。在其中,您可以简单地将复选标记放在您想要的行旁边,然后在底部单击“导出”并选择 SQL。它将为您选择的任何记录提供 INSERT 语句。希望这可以帮助。
你可以试试这个
function get_insert_query($pdo, $table, $where_sth)
{
$sql = "";
$row_data = $pdo->query("SELECT * FROM `{$table}` WHERE $where_sth")->fetch();
if($row_data){
$sql = "INSERT INTO `$table` (";
foreach($row_data as $col_name => $value){
$sql .= "`".$col_name."`, ";
}
$sql = rtrim($sql, ", ");
$sql .= ") VALUES (";
foreach($row_data as $col_name => $value){
if (is_string($value)){
$value = $pdo->quote($value);
} else if ($value === null){
$value = 'NULL';
}
$sql .= $value .", ";
}
$sql = rtrim($sql, ", ");
$sql .= ");";
}
return $sql;
}
要使用它,只需调用:
$pdo = new PDO( "connection string goes here" );
$sql = get_insert_query($pdo, 'texts', "text_id = 959");
echo $sql;
更新在 PhpMyAdmin 中获取当前寄存器的插入语句:
从您的数据库中选择表格以从顶部菜单的“导出”选项卡中获取寄存器,如下图所示
https://i.stack.imgur.com/kDUg8.png
自定义导出 下移至“数据创建选项”
https://i.stack.imgur.com/xf0vf.png
在那里,以您喜欢的语法选择“插入”功能
它非常简单。您所要做的就是在一个静态块中编写一个插入语句,然后将它作为一个脚本作为一个完整的块运行。
例如,如果您想从表(例如 ENGINEER_DETAILS)中获取选定行的插入语句,那么您必须运行此块 -
spool
set sqlformat insert
select * from ENGINEER_DETAILS where engineer_name like '%John%';
spool off;
该块的输出将是插入语句。
根据您的意见,您的目标是将数据库更改从开发环境迁移到生产环境。
最好的方法是将数据库更改保留在源代码中,然后在源代码控制系统(例如 git 或 svn)中跟踪它们。
您可以通过以下方式快速启动并运行:https://github.com/davejkiger/mysql-php-migrations
作为 PHP 中一个非常基本的自定义解决方案,您可以使用如下函数:
function store_once($table, $unique_fields, $other_fields=array()) {
$where = "";
$values = array();
foreach ($unique_fields as $k => $v) {
if (!empty($where)) $where .= " && ";
$where .= "$k=?";
$values[] = $v;
}
$records = query("SELECT * FROM $table WHERE $where", $values);
if (false == $records) {
store($table, array_merge($unique_fields, $other_fields));
}
}
然后您可以创建一个迁移脚本,它将根据您的规范更新任何环境。
--hex-blob
如果您有 blob 列(例如bit(1)
),它会将其写为字符串,否则在执行 INSERT 时可能会导致Unknown command '\0'
错误。--compact
来消除所有的繁琐,只得到insert
语句本身。