GVKun编程网logo

在python中使用带有MySQL的预准备语句

14

如果您对在python中使用带有MySQL的预准备语句感兴趣,那么这篇文章一定是您不可错过的。我们将详细讲解在python中使用带有MySQL的预准备语句的各种细节,此外还有关于Grails中使用gr

如果您对在python中使用带有MySQL的预准备语句感兴趣,那么这篇文章一定是您不可错过的。我们将详细讲解在python中使用带有MySQL的预准备语句的各种细节,此外还有关于Grails中使用groovy.sql.Sql或JDBC的连接池和预准备语句、MySql在Python中的应用:如何使用Python语言进行MySQL开发、Perl DBI(MySQL)在预准备语句中放置单引号而不是实际参数、PHP MySQL – 如何在预准备语句中插入默认值的实用技巧。

本文目录一览:

在python中使用带有MySQL的预准备语句

在python中使用带有MySQL的预准备语句

我正在尝试将SQL与Python中准备好的语句一起使用。Python对此没有自己的机制,因此我尝试直接使用SQL:

sql = "PREPARE stmt FROM ' INSERT INTO {} (date,time,tag,power) VALUES (?,?,?)'".format(self.db_scan_table)
self.cursor.execute(sql)

然后,在循环中:

sql = "EXECUTE stmt USING \'{}\',\'{}\',{},{};".format(d,t,power)
self.cursor.execute(sql)

在循环中,我得到:

MySQL Error [1064]: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''2014-12-25','12:31:46',88000000,-6.64' at line 1

这是怎么回事?

Grails中使用groovy.sql.Sql或JDBC的连接池和预准备语句

Grails中使用groovy.sql.Sql或JDBC的连接池和预准备语句

今天遇到这个问题: Grails query not using GORM我想知道使用groovy.sql.sql或JDBC是否带有连接池的好处?

在某些情况下,我可以看到GOrmless如何有益,但缺乏conn pooling会将其作为一种选择.

我们还能从准备好的陈述中获益吗?

解决方法

DataSource的主要用途之一是提供 connection pooling.如果在DataSource.groovy中设置了pooled = true,则在执行查询时,注入的dataSource将为您提供池中的连接.

Groovy sql还使用预准备语句提供查询:

def sql = new sql(dataSource)
def params = [10,''Groovy'',''http://groovy.codehaus.org'']
sql.execute ''insert into PROJECT (id,name,url) values (?,?,?)'',params

您还可以在sql对象上启用PreparedStatement缓存以获得性能:

sql.cacheStatements = true

MySql在Python中的应用:如何使用Python语言进行MySQL开发

MySql在Python中的应用:如何使用Python语言进行MySQL开发

mysql是一种流行的开源关系型数据库管理系统,被广泛应用于web开发和其他各种应用程序中。在python语言中,我们可以使用各种库来与mysql进行交互和开发。在本文中,我们将讨论如何使用python语言进行mysql开发。

第一步:安装MySQL驱动程序

在Python中使用MySQL需要使用MySQL驱动程序。 Python中有多个MySQL驱动程序供选择,包括mysql-connector-python、PyMySQL、MySQLdb等。在本文中,我们将使用mysql-connector-python驱动程序,因为它是最受欢迎的驱动程序之一。

安装mysql-connector-python可以使用pip工具,只需要在命令行中输入以下命令即可:

pip install mysql-connector-python
登录后复制

第二步:连接MySQL数据库

立即学习“Python免费学习笔记(深入)”;

点击下载“修复打印机驱动工具”;

在开始MySQL开发之前,我们需要建立与MySQL数据库的连接。要连接MySQL数据库,您需要提供以下信息:

  • 主机(IP地址)
  • 用户名
  • 密码
  • 数据库名称

使用mysql-connector-python驱动程序连接MySQL数据库的示例代码如下:

import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",
  user="yourusername",
  passwd="yourpassword",
  database="yourdatabase"
)

print(mydb)
登录后复制

如果连接成功,您将看到数据库连接对象的详细信息。

第三步:创建数据库表

在MySQL中,数据存储在表中。要在Python中创建表,需要使用CREATE语句。下面是一个简单的例子:

import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",
  user="yourusername",
  passwd="yourpassword",
  database="yourdatabase"
)

mycursor = mydb.cursor()

mycursor.execute("CREATE TABLE customers (name VARCHAR(255), address VARCHAR(255))")
登录后复制

在这个例子中,我们创建了一个名为“customers”的表,其中包含名字和地址列。

第四步:插入数据

要在表中插入数据,需要使用INSERT语句。 下面是一个示例代码:

import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",
  user="yourusername",
  passwd="yourpassword",
  database="yourdatabase"
)

mycursor = mydb.cursor()

sql = "INSERT INTO customers (name, address) VALUES (%s, %s)"
val = ("John", "Highway 21")

mycursor.execute(sql, val)

mydb.commit()

print(mycursor.rowcount, "record inserted.")
登录后复制

在这个例子中,我们向“customers”表插入了一个名为John的新客户和他的地址。

第五步:查询数据

要从表中检索数据,需要使用SELECT语句。下面是一个示例代码:

import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",
  user="yourusername",
  passwd="yourpassword",
  database="yourdatabase"
)

mycursor = mydb.cursor()

mycursor.execute("SELECT * FROM customers")

myresult = mycursor.fetchall()

for x in myresult:
  print(x)
登录后复制

在这个例子中,我们检索了“customers”表中的所有数据,并循环打印每个记录的值。

第六步:更新数据

要更新表中的数据,需要使用UPDATE语句。 下面是一个示例代码:

import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",
  user="yourusername",
  passwd="yourpassword",
  database="yourdatabase"
)

mycursor = mydb.cursor()

sql = "UPDATE customers SET address = ''Canyon 123'' WHERE name = ''John''"

mycursor.execute(sql)

mydb.commit()

print(mycursor.rowcount, "record(s) affected")
登录后复制

在这个例子中,我们将John的地址从“Highway 21”更新为“Canyon 123”。

第七步:删除数据

要从表中删除数据,需要使用DELETE语句。 下面是一个示例代码:

import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",
  user="yourusername",
  passwd="yourpassword",
  database="yourdatabase"
)

mycursor = mydb.cursor()

sql = "DELETE FROM customers WHERE name = ''John''"

mycursor.execute(sql)

mydb.commit()

print(mycursor.rowcount, "record(s) deleted")
登录后复制

在这个例子中,我们删除了名为“John”的客户记录。

结束语

MySQL是一种强大的关系型数据库管理系统,可以帮助我们存储和管理数据。通过使用Python语言的各种库,我们可以轻松地与MySQL数据库进行交互,从而使我们的数据库开发更加高效和简单。在本文中,您学习了如何使用Python进行MySQL开发的基本步骤,包括连接到数据库、创建表、插入、查询、更新和删除数据。通过这些基础知识,您可以构建复杂的数据库应用程序,以满足您的特定需求。

以上就是MySql在Python中的应用:如何使用Python语言进行MySQL开发的详细内容,更多请关注php中文网其它相关文章!

Perl DBI(MySQL)在预准备语句中放置单引号而不是实际参数

Perl DBI(MySQL)在预准备语句中放置单引号而不是实际参数

我正在尝试做一个简单的查询作为准备好的声明,但没有成功.这是代码:
package sqltest;
use DBI;

DBI->trace(2);

my $dbh = DBI->connect('dbi:MysqL:database=test;host=***;port=3306','the_username','****');
my $prep = 'SELECT me.id,me.session_data,me.expires FROM sys_session me WHERE me.id = ?';
$dbh->{raiseerror} = 1;
my $sth = $dbh->prepare($prep);
$sth->bind_param(1,'session:06b6d2138df949524092eefc066ee5ab3598bf96');
$sth->execute;
DBI::dump_results($sth);

MysqL服务器响应”’附近的语法错误.

DBI跟踪的输出显示

-> bind_param for DBD::MysqL::st (DBI::st=HASH(0x21e35cc)~0x21e34f4 1 'session:06b6d2138df949524092eefc066ee5ab3598bf96') thr#3ccdb4
 Called: dbd_bind_ph
  <- bind_param= ( 1 ) [1 items] at perl_test_dbi_params.pl line 10
[...]
>parse_params statement SELECT me.id,me.expires FROM sys_session me WHERE me.id = ?
Binding parameters: SELECT me.id,me.expires FROM sys_session me WHERE me.id = '
[...]
DBD::MysqL::st execute Failed: You have an error in your sql Syntax; check the manual that corresponds to your MysqL server version for the right Syntax to use near ''' at line 1

所以对我而言,看起来声明并没有得到应有的准备.
当我发送没有参数的查询时,它按预期工作.

我在这里想念什么?

DBI版本是DBI 1.637-ithread,MysqL版本是5.5.57-0 deb8u1

使用针对MSWin32-x86-multi-thread-64int构建的Windows perl 5,版本26,subversion 1(v5.26.1)进行测试
和Ubuntu perl 5,版本22,颠覆1(v5.22.1)为x86_64-linux-gnu-thread-multi构建

EDIT1:
for context:我在使用Catalyst和Catalyst::Plugin::Session::Store::DBIC时注意到了这个问题.这里,id-column是一个Varchar(72)类型,它包含一个session-id.

EDIT2:

> DBD :: MysqL版本是4.043
>通过$sth->执行绑定(‘session:foo’);导致同样的问题
>通过$sth-> bind_param绑定(‘session:foo’,sql_VARCHAR);导致同样的问题
>绑定数字字段确实有效,但只能使用显式类型定义$sth-> bind_param(1,1512407082,sql_INTEGER);

EDIT3:
我找到了做更多测试的时间,但没有令人满意的结果:

>我能够使用较旧的服务器进行测试并且有效. DBI和DBD :: MysqL的版本是相同的,但我发现服务器使用的是MysqL 5.5客户端,在DBI-trace中报告为MysqL_VERSION_ID 50557,而我的两个原始测试服务器都使用MysqL 5.7 MysqL_VERSION_ID 50720和MysqL_VERSION_ID 50716
>使用$dbh-> {MysqL_server_prepare} = 1;它有效!也许这有助于找到这个问题的人,但我现在更愿意找到问题的真正原因

解决方法

从您的跟踪日志可以看出,问号占位符(?)被DBD :: MysqL替换为一个撇号(‘).所以它是纯DBD :: MysqL的bug.乍一看它完全没有意义……因为占位符被放入两个撇号的参数替换.

可以在那里找到执行此占位符替换的相关代码:https://metacpan.org/source/MICHIELB/DBD-mysql-4.043/dbdimp.c#L784-786

*ptr++ = '\'';
          ptr += MysqL_real_escape_string(sock,ptr,valbuf,vallen);
          *ptr++ = '\'';

所以问题是,上面的C代码可以在* ptr缓冲区中产生一个撇号吗?答案是肯定的,当MysqL_real_escape_string()返回相同值的整数作为指针大小减去1 – 当两个撇号被写入* ptr缓冲区中的相同位置时,模拟递减1的数值运算.

这会发生吗?是的,它可以,因为Oracle在MysqL 5.7.6客户端库中更改了MysqL_real_escape_string()C函数的API:

https://dev.mysql.com/doc/relnotes/mysql/5.7/en/news-5-7-6.html#mysqld-5-7-6-feature

Incompatible Change: A new C API function,MysqL_real_escape_string_quote(),has been implemented as a replacement for MysqL_real_escape_string() because the latter function can fail to properly encode characters when the NO_BACKSLASH_ESCAPES sql mode is enabled. In this case,MysqL_real_escape_string() cannot escape quote characters except by doubling them,and to do this properly,it must kNow more information about the quoting context than is available. MysqL_real_escape_string_quote() takes an extra argument for specifying the quoting context. For usage details,see MysqL_real_escape_string_quote().

MysqL 5.7.6版本的MysqL_real_escape_string()文档说:

https://dev.mysql.com/doc/refman/5.7/en/mysql-real-escape-string.html

Return Values: The length of the encoded string that is placed into the to argument,not including the terminating null byte,or -1 if an error occurs.

因此,如果在MysqL服务器上启用NO_BACKSLASH_ESCAPES sql模式,则MysqL 5.7.6客户端的MysqL_real_escape_string()无法正常工作并返回错误,因此-1会转换为unsigned long. unsigned long在32bit和64bit x86平台上都与指针大小相同,因此在DBD :: MysqL驱动程序的C代码之上产生一个撇号字符.

现在我在下面的pull请求中修复了DBD::MariaDB驱动程序(DBD :: MysqL的fork)的这个问题:https://github.com/gooddata/DBD-MariaDB/pull/77

所以当使用MysqL 5.7客户端库编译时,DBD :: MariaDB也是兼容的.

PHP MySQL – 如何在预准备语句中插入默认值

PHP MySQL – 如何在预准备语句中插入默认值

假设我有一个准备好的声明,如下所示:

$insertsql = "";
$insertsql .= "INSERT INTO table";
$insertsql .= "(tag,month_interval,month_interval_lastupdated,date_due,date_due_lastupdated,date_completion,date_completion_lastupdated,";
$insertsql .= "activeNotification,date_lastmodified) ";
$insertsql .= "VALUES (?,?,Now(),?,Now(),?,Now(),?,Now())";

但有时这些问号中的一些不会被设定.

是否有一个关键字我可以在准备好的语句中替换,告诉MysqL插入默认值?

就像是:

if($stmt = $MysqLi->prepare($insertsql)) {
   if(!isset($tag)) {
      // code to find first question mark and replace w/ default value
      }
      $stmt->bind_param('sisss',$tag,$month_interval,$date_due,$date_completion);
      $stmt->execute();
}

日期字段的默认值为“1000-01-01 00:00:00”,month_interval的默认值为0,其余字段的默认值为NULL.

解决方法:

在我看来,你的问题涉及一个有趣的主题.

通过快速搜索,我没有找到任何预定义的解决方案,但我将在接下来的几天继续搜索.

我已经详细说明了解决方案,但它有点扭曲而且不完全干净.

首先,我用占位符重新定义查询:

$query = "
    INSERT INTO table
                (
                    tag,
                    month_interval,
                    month_interval_lastupdated,
                    date_due,
                    date_due_lastupdated,
                    date_completion,
                    date_completion_lastupdated,
                    activeNotification,
                    date_lastmodified
                )
         VALUES (<tag>,<month_interval>,Now(),<date_due>,Now(),<date_completion>,Now(),<activeNotification>,Now())
";

在这个例子中,我使用<>围绕占位符,但您可以选择首选占位符,确保它们不会与查询的其他元素混淆.

然后,我初始化一个关联数组,其中键作为占位符名称和要绑定的值,以及一个带有完整绑定类型集的变量($types):

$values = array( 'tag'=>$tag, 'month_interval'=>$month_interval, 'date_due'=>$date_due, 'date_completion'=>$date_completion, 'activeNotification'=>$activeNotification );
$types = 'sisss';

然后,最重要的一句话.我以这种奇怪的方式初始化一个数组:

$bind = array( Null, '' );

索引0设置为Null,因为是为stmt对象保留的(在下面创建);索引1是一个空字符串,将填充必要的绑定类型.

现在我执行一个foreach循环遍历数组$values的所有元素:

$i = 0;
foreach( $values as $key => $val )
{
    if( is_null( $val ) )
    {
        $query = str_replace( '<'.$key.'>', 'DEFAULT', $query );
    }
    else
    {
        $query    = str_replace( '<'.$key.'>', '?', $query );
        $bind[1] .= $types[$i];
        $bind[]   = &$val;
    }
    $i++;
}

在该循环中,如果值为null,则使用MysqL关键字DEFAULT替换相应查询的占位符.否则,我用一个?替换占位符,我将相应的$types子字符串添加到$bind [1],然后将值(通过引用)附加到$bind数组.

此时,真正的查询已准备就绪,我可以准备它:

$stmt = $db->prepare( $query ) or die( $stmt->error );

并且,如果没有默认值(count($bind)> 2),我可以绑定它:

if( count($bind)>2 )
{
    $bind[0] = $stmt;
    call_user_func_array( 'MysqLi_stmt_bind_param', $bind );
}

如前所述,我将$bind [0]设置为由> prepare返回的stmt对象,然后我使用call_user_func_array来执行MysqLi_stmt_bind_param.我不能直接调用 – > bind_param因为我有一个变量参数号.

在这个古怪的过程结束时,我终于可以执行查询:

$stmt->execute() or die( $stmt->error );

我已经测试了这段代码,但它确实有效.

主要问题在于is_null($val):使用数组,我不能使用isset作为测试,因为数组的每个元素都是设置的.如果包含允许Null值的占位符的所有字段都具有Null广告默认值,则代码将起作用.

今天关于在python中使用带有MySQL的预准备语句的分享就到这里,希望大家有所收获,若想了解更多关于Grails中使用groovy.sql.Sql或JDBC的连接池和预准备语句、MySql在Python中的应用:如何使用Python语言进行MySQL开发、Perl DBI(MySQL)在预准备语句中放置单引号而不是实际参数、PHP MySQL – 如何在预准备语句中插入默认值等相关知识,可以在本站进行查询。

本文标签: