Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/99.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 直接按名称绑定SQLite参数_Objective C_Ios_Xcode_Sqlite_Parameters - Fatal编程技术网

Objective c 直接按名称绑定SQLite参数

Objective c 直接按名称绑定SQLite参数,objective-c,ios,xcode,sqlite,parameters,Objective C,Ios,Xcode,Sqlite,Parameters,我最近开始学习如何为iOS编程,并且(在我看来)被SQLite3中一个明显的疏忽所困扰。让我证明一下,在上周之前,我在Mac、Objective C、Xcode、iOS或SQLite方面没有任何(实际)经验,因此,我不会妄想跳进久经考验的真正工具领域,并在第一次尝试时发现明显的错误。我想这是一个很好的解释 然而,在过去几个月使用SQLServer、MySQL和PostgreSQL之后,我惊奇地发现SQLite没有更好的按名称添加参数的功能。我能在网上找到的所有东西(文档、论坛[包括SO])都说要

我最近开始学习如何为iOS编程,并且(在我看来)被SQLite3中一个明显的疏忽所困扰。让我证明一下,在上周之前,我在Mac、Objective C、Xcode、iOS或SQLite方面没有任何(实际)经验,因此,我不会妄想跳进久经考验的真正工具领域,并在第一次尝试时发现明显的错误。我想这是一个很好的解释

然而,在过去几个月使用SQLServer、MySQL和PostgreSQL之后,我惊奇地发现SQLite没有更好的按名称添加参数的功能。我能在网上找到的所有东西(文档、论坛[包括SO])都说要使用它们的整数索引分配参数,如果你修改你的查询,这似乎是一件痛苦的事情。即使您可以在语句中命名参数并执行以下操作

sqlite3_bind_int(stmt, sqlite3_bind_parameter_index(stmt, "@my_param"), myInt);
似乎也没有人这样做。事实上,似乎根本没有人试图将其自动化;我所能找到的唯一方法是使用参数数组和循环计数器,并检查每个参数以确定要插入的对象类型。我最初考虑过一种类似的方法,但a)我老板的立场是,数据库参数应该始终进行类型检查(我同意,尽管我意识到SQLite字段不是强类型的,从技术上讲,我无论如何都可以这样做),b)这感觉像是一种不雅观的黑客行为,c)我认为这种方法没有被广泛使用是有原因的。因此:

1) 为什么SQLite中没有接受参数名(比如“const char”)的绑定方法?还是有我遗漏了什么

2) 为什么没有人使用上面的例子

我深入研究了一下源代码,认为我可以轻松地修改库,或者只编写我自己的(类型化的)类方法来完成上述工作,但我假设没有人将其构建到SQLite中是有原因的。我唯一的猜测是,在[insert iDevice here]上查找参数索引所需的额外内存和周期太宝贵了,不值得使用参数名带来的便利

如有任何见解,将不胜感激

  • 有,;您提到的函数用于将参数名转换为索引,然后可以与函数一起使用。但是,没有
    sqlite3\u bind\u*\u by\u name()
    函数或类似的函数。这有助于防止API膨胀。如果您对如何使用它感兴趣,那么popular在它的一个分支中支持命名参数

    如果您考虑实现完全命名的参数绑定方法,那么请考虑当前代码“<代码> BIN < /代码>函数:

    int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
    int sqlite3_bind_double(sqlite3_stmt*, int, double);
    int sqlite3_bind_int(sqlite3_stmt*, int, int);
    int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
    int sqlite3_bind_null(sqlite3_stmt*, int);
    int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));
    int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
    int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
    int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
    
    如果我们想添加对命名参数的显式支持,该列表的长度将加倍,以包括:

    int sqlite3_bind_name_blob(sqlite3_stmt*, const char*, const void*, int n, void(*)(void*));
    int sqlite3_bind_name_double(sqlite3_stmt*, const char*, double);
    int sqlite3_bind_name_int(sqlite3_stmt*, const char*, int);
    int sqlite3_bind_name_int64(sqlite3_stmt*, const char*, sqlite3_int64);
    int sqlite3_bind_name_null(sqlite3_stmt*, const char*);
    int sqlite3_bind_name_text(sqlite3_stmt*, const char*, const char*, int n, void(*)(void*));
    int sqlite3_bind_name_text16(sqlite3_stmt*, const char*, const void*, int, void(*)(void*));
    int sqlite3_bind_name_value(sqlite3_stmt*, const char*, const sqlite3_value*);
    int sqlite3_bind_name_zeroblob(sqlite3_stmt*, const char*, int n);
    
    两倍多的函数意味着维护API、确保向后兼容性等所花费的时间要多得多。然而,通过简单地引入
    sqlite3\u bind\u parameter\u index()
    ,他们能够用一个函数添加对命名参数的完全支持。这意味着,如果他们决定支持新的绑定类型(可能是
    sqlite3\u bind\u int128
    ),他们只需要添加一个函数,而不是两个

  • 至于为什么没有人使用它。。。我无法通过调查给出任何明确的答案。我的猜测是,按顺序引用参数更自然一些,在这种情况下,命名参数就没有那么有用了。命名参数似乎只有在需要无序引用参数时才有用


  • SQLite确实提供了以下功能:有用的资源——但不确定它与我的问题有什么关系?对我来说,命名参数对我的精神负担较小,正如Tim所说,SQLite支持它。像.NET这样的语言使命名参数更容易访问。从维护的角度来看是有意义的。。。但是你可以只使用以'name'为参数的方法,而放弃那些以'int'为参数的方法(除了向后兼容之外,但是你必须在某个时候进行跳跃)。我仍然感到惊讶的是,SQLite标准是在其他所有SQL数据库系统(至少我知道)使用命名参数时按顺序列出它们——对我来说,这正是为了让您可以在不担心顺序的情况下使用它们。感谢您的链接,接下来我将不得不研究SQLite包装:)@brichins,您可以准备一条语句并将参数索引读入变量一次,然后重用准备好的语句并多次将不同的参数绑定到它。这避免了对每个参数进行字典查找。放弃基于索引的API会迫使人们降低效率,所以如果真的发生这种情况,我会感到惊讶;-)。