首页 \ 问答 \ 在mysqli预处理语句程序样式中获取最后一个插入id的正确方法是什么?(Which is correct way to get last inserted id in mysqli prepared statements procedural style?)

在mysqli预处理语句程序样式中获取最后一个插入id的正确方法是什么?(Which is correct way to get last inserted id in mysqli prepared statements procedural style?)

我正在使用mysqli预处理语句在这样的表中插入记录

$link = mysqli_connect('localhost', 'my_user', 'my_password', 'world');

/* check connection */
if (!$link) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$stmt = mysqli_prepare($link, "INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)");
mysqli_stmt_bind_param($stmt, 'sssd', $code, $language, $official, $percent);

$code = 'DEU';
$language = 'Bavarian';
$official = "F";
$percent = 11.2;

/* execute prepared statement */
mysqli_stmt_execute($stmt);

if(mysqli_stmt_affected_rows($stmt) > 0){
//if insert is successful then get the insrted id.


}

/* close statement and connection */
mysqli_stmt_close($stmt);

/* close connection */
mysqli_close($link);

并且想获得最后插入的id,因为该表具有record_num字段,该字段是自动增量。

所以我的问题是我应该在函数内放置连接名称或语句名称。

即1)

echo mysqli_insert_id($link);

资料来源: http//php.net/manual/en/mysqli.insert-id.php

2)

echo mysqli_stmt_insert_id($stmt);

资料来源: http//php.net/manual/en/mysqli-stmt.insert-id.php

哪一个是正确的? $ stmt中哪一个会给我最后一个ins id?

  • 没有其他插入使用相同的stmt同一页面进行。*

更新:

根据http://php.net/manual/en/mysqli-stmt.insert-id.php的说明

我只做单插入,所以我想我可以使用

mysqli_stmt_insert_id($stmt)

但是在使用预处理语句进行多次插入时

echo mysqli_insert_id($link);

是最好的做法。


i am using mysqli prepared statement to insert record in the table like this

$link = mysqli_connect('localhost', 'my_user', 'my_password', 'world');

/* check connection */
if (!$link) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$stmt = mysqli_prepare($link, "INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)");
mysqli_stmt_bind_param($stmt, 'sssd', $code, $language, $official, $percent);

$code = 'DEU';
$language = 'Bavarian';
$official = "F";
$percent = 11.2;

/* execute prepared statement */
mysqli_stmt_execute($stmt);

if(mysqli_stmt_affected_rows($stmt) > 0){
//if insert is successful then get the insrted id.


}

/* close statement and connection */
mysqli_stmt_close($stmt);

/* close connection */
mysqli_close($link);

and would like to get the last inserted id , as the table has record_num field which is auto increment .

so my question is should i place connection name or the statement name inside the function.

i.e 1)

echo mysqli_insert_id($link);

Source: http://php.net/manual/en/mysqli.insert-id.php

2)

echo mysqli_stmt_insert_id($stmt);

Source: http://php.net/manual/en/mysqli-stmt.insert-id.php

which one is correct ? which one will give me last insrted id by the $stmt ?

  • there are no other inserts are being done using the same stmt one the same page..*

Update:

according to the note from http://php.net/manual/en/mysqli-stmt.insert-id.php

I am doing only single insert so i guess i can use

mysqli_stmt_insert_id($stmt)

but while doing multiple inserts using prepared statements using

echo mysqli_insert_id($link);

is best practice.


原文:https://stackoverflow.com/questions/25226740
更新时间:2022-03-28 17:03

最满意答案

您的问题下的评论应该指向另一个解决方案。 在这里,我想给出一个解释,为什么你得到一个数组,而不是一个对象。

在这一行:


isValidUser = users.objects.filter(email=req_email, password=req_password)

你使用filter方法,它可能返回多于1个结果(或没有)。 无论结果的数量如何,您总是会获得一个数组(python中的列表)。 filter()方法返回一个新的QuerySet

如果要显式检索单个结果,并且模型类中有唯一字段,则应使用get()方法,该方法不返回QuerySet,而是返回对象。

因此,如果将字段email设置为唯一,则可以执行以下操作:


isValidUser = users.objects.get(email=req_email)

如果有一个可以匹配的条目,那将返回一个对象。

此外,遵循Python的命名约定并使用snake case命名变量是一个好习惯:

is_valid_user

代替

isValidUser

The comments under your questions should point you to another solution. Here I'd like to give an explanation, why you're getting an array, and not an object.

In this line:


isValidUser = users.objects.filter(email=req_email, password=req_password)

you use the filter method, which may return more than 1 result (or none). You'll always get an array (a list in python), regardless of the number of results. The filter() method returns a new QuerySet.

If you want to retrieve a single result explicitly, and you have a unique field in your model class, then you should use the method get(), which doesn't return a QuerySet, but an object.

So if, let's say the field email is set to be unique, you could do this:


isValidUser = users.objects.get(email=req_email)

That will return an object, if there is an entry that can be matched.

Also, it is a good practice to follow the naming conventions for Python and name the variables with snake case:

is_valid_user

instead of

isValidUser

相关问答

更多
  • 如果你想获得一个对象,使用get()更直接: obj = Class.objects.get(pk=this_object_id) If you want to get an object, using get() is more straightforward: obj = Class.objects.get(pk=this_object_id)
  • django-filter (和REST框架相应的基于django-filter的过滤后端 )确实是最接近你想要的开箱即用的应用程序,但是你发现它并不完全支持用例你需要,特别是因为: 它不支持querystring中的null / None键。 它不支持使用逗号分隔的__in样式查找。 (我对上述任何一个/两个都可能是错的,但这就是我从环绕源/文档看起来的样子) 这意味着您的选择可能是: 编写自己的过滤,以完全按照您的需要行事。 为django-filter贡献对上述两个问题的支持。 寻找替代过滤应用程序 ...
  • 通常你会使用get_or_create 。 model_instance = MyModel.objects.get_or_create(surname='foo') 你不应该真的使用management.call_command的东西。 也就是说,如果我误解了你并且你有充分的理由,试试这个: try: MyModel.objects.get(surname='foo') except MyModel.DoesNotExist: management.call_command(.... ...
  • 当Django删除一个对象时,它会尝试模拟相关对象的级联删除,以确保它们的delete方法和相关信号被调用。 请参阅https://docs.djangoproject.com/en/stable/topics/db/queries/#deleting-objects 当Django删除一个对象时,默认情况下它会模拟SQL约束ON DELETE CASCADE的行为 - 换句话说,任何有外键指向要删除的对象的对象都将被删除。 使用Django 1.5+,您可以通过将外键设置为on_delete=DO_NOT ...
  • 作为包含标签这没有意义。 特别是因为你似乎正在使用它在你已经告诉它呈现相同的模板。 你需要的是一个赋值标签 : @register.assignment_tag def get_random_testimonial(): return Testimonials.objects.order_by('?')[0] 那你可以这样做: {% get_random_testimonial as my_testimonial %} {{ my_testimonial.text }} {{ my_testimo ...
  • 您的问题下的评论应该指向另一个解决方案。 在这里,我想给出一个解释,为什么你得到一个数组,而不是一个对象。 在这一行: isValidUser = users.objects.filter(email=req_email, password=req_password) 你使用filter方法,它可能返回多于1个结果(或没有)。 无论结果的数量如何,您总是会获得一个数组(python中的列表)。 filter()方法返回一个新的QuerySet 。 如果要显式检索单个结果,并且模型类中有唯一字段,则应使用 ...
  • 不要在标签中查询Product ,而是返回 return { 'menu_sections': MenuSection.objects.all() } 然后,在您的模板中, {% for menu_section in menu_sections %} {{ menu_section.name }} {% for product in menu_section.product_set.all %} {{ product.name }} {% endfor % ...
  • 你可以做: Author.objects.get(pk=author1.pk) 假设你想用相同的主键查找作者。 它只会返回自己。 使用实例查询外键字段只需查询主键,因此上面的内容大致等同于外键案例。 编辑: 如果你真的想要基于每个字段名称进行查询(尽管我不能想到用例),你可以使用Meta API : Author.objects.get( **{field.name: getattr(author1, field.name) for field in author1._meta.g ...
  • 如果您正在尝试编写一个函数来获取可以通过Presence对象与Drink关联的所有Users ,则可以使用User与Presence的反向关系。 而不是试图从Presence并获得Users列表。 from django.contrib.auth.models import User ... class Drink(model.Models): ... def get_present_users(self): return User.objects.filter(pre ...
  • prefetch_related()方法将为您要预取的每个查找执行数据库查询。 基本上,在这里,Django将执行第一个数据库查询以获取您的Unit实例,然后执行另外两个查询以获取Order和Report实例。 因此,一旦执行了Unit.obects.filter(...).prefetch_related(...) queryset,每个Unit实例都将缓存其相关的Order和Report对象(不需要更多的数据库查询来获取这些数据)。 views.py 从Django 1.7开始, prefetch_re ...

相关文章

更多

最新问答

更多
  • 您如何使用git diff文件,并将其应用于同一存储库的副本的本地分支?(How do you take a git diff file, and apply it to a local branch that is a copy of the same repository?)
  • 将长浮点值剪切为2个小数点并复制到字符数组(Cut Long Float Value to 2 decimal points and copy to Character Array)
  • OctoberCMS侧边栏不呈现(OctoberCMS Sidebar not rendering)
  • 页面加载后对象是否有资格进行垃圾回收?(Are objects eligible for garbage collection after the page loads?)
  • codeigniter中的语言不能按预期工作(language in codeigniter doesn' t work as expected)
  • 在计算机拍照在哪里进入
  • 使用cin.get()从c ++中的输入流中丢弃不需要的字符(Using cin.get() to discard unwanted characters from the input stream in c++)
  • No for循环将在for循环中运行。(No for loop will run inside for loop. Testing for primes)
  • 单页应用程序:页面重新加载(Single Page Application: page reload)
  • 在循环中选择具有相似模式的列名称(Selecting Column Name With Similar Pattern in a Loop)
  • System.StackOverflow错误(System.StackOverflow error)
  • KnockoutJS未在嵌套模板上应用beforeRemove和afterAdd(KnockoutJS not applying beforeRemove and afterAdd on nested templates)
  • 散列包括方法和/或嵌套属性(Hash include methods and/or nested attributes)
  • android - 如何避免使用Samsung RFS文件系统延迟/冻结?(android - how to avoid lag/freezes with Samsung RFS filesystem?)
  • TensorFlow:基于索引列表创建新张量(TensorFlow: Create a new tensor based on list of indices)
  • 企业安全培训的各项内容
  • 错误:RPC失败;(error: RPC failed; curl transfer closed with outstanding read data remaining)
  • C#类名中允许哪些字符?(What characters are allowed in C# class name?)
  • NumPy:将int64值存储在np.array中并使用dtype float64并将其转换回整数是否安全?(NumPy: Is it safe to store an int64 value in an np.array with dtype float64 and later convert it back to integer?)
  • 注销后如何隐藏导航portlet?(How to hide navigation portlet after logout?)
  • 将多个行和可变行移动到列(moving multiple and variable rows to columns)
  • 提交表单时忽略基础href,而不使用Javascript(ignore base href when submitting form, without using Javascript)
  • 对setOnInfoWindowClickListener的意图(Intent on setOnInfoWindowClickListener)
  • Angular $资源不会改变方法(Angular $resource doesn't change method)
  • 在Angular 5中不是一个函数(is not a function in Angular 5)
  • 如何配置Composite C1以将.m和桌面作为同一站点提供服务(How to configure Composite C1 to serve .m and desktop as the same site)
  • 不适用:悬停在悬停时:在元素之前[复制](Don't apply :hover when hovering on :before element [duplicate])
  • 常见的python rpc和cli接口(Common python rpc and cli interface)
  • Mysql DB单个字段匹配多个其他字段(Mysql DB single field matching to multiple other fields)
  • 产品页面上的Magento Up出售对齐问题(Magento Up sell alignment issue on the products page)