iOS SQlite3 常用命令

使用的过程根据使用的函数大致分为如下几个过程:

sqlite3_open()

sqlite3_prepare()

sqlite3_step()

sqlite3_column()

sqlite3_finalize()

sqlite3_close()

1.sqlite3_open()

打开数据库,在操作数据库之前,首先要打开数据库。这个函数打开一个sqlite数据库文件的连接并且返回一个数据库连接对象。这个操作同时程序中的第一个调用的sqlite函数,同时也是其他sqlite api的先决条件。许多的sqlite接口函数都需要一个数据库连接对象的指针作为它们的第一个参数。

相关函数

SQLITE_APIintsqlite3_open(

  const char*filename,  /* Database filename (UTF-8) */

  sqlite3**ppDb          /* OUT: SQLite db handle */

);

SQLITE_APIintsqlite3_open16(

  const void*filename,  /* Database filename (UTF-16) */

  sqlite3**ppDb          /* OUT: SQLite db handle */

);

SQLITE_APIintsqlite3_open_v2(

  const char*filename,  /* Database filename (UTF-8) */

  sqlite3**ppDb,        /* OUT: SQLite db handle */

  intflags,              /* Flags */

  const char*zVfs        /* Name of VFS module to use */

);

说明:假如这个要被打开的数据文件不存在,则一个同名的数据库文件将被创建。如果使用sqlite3_open和sqlite3_open_v2的话,数据库将采用UTF-8的编码方式,sqlite3_open16采用UTF-16的编码方式。

返回值:如果sqlite数据库被成功打开(或创建),将会返回SQLITE_OK,否则将会返回错误码。Sqlite3_errmsg()或者sqlite3_errmsg16可以用于获得数据库打开错误码的英文描述,这两个函数定义为:

const char *sqlite3_errmsg(sqlite3*);

const void *sqlite3_errmsg16(sqlite3*);

无论是否成功打开数据库, 都应该使用 sqlite3_close() 关闭数据库连接.

参数说明:

filename:需要被打开的数据库文件的文件名,在sqlite3_open和sqlite3_open_v2中这个参数采用UTF-8编码,而在sqlite3_open16中则采用UTF-16编码。

ppDb:一个数据库连接句柄被返回到这个参数,即使发生错误。唯一的一场是如果sqlite不能分配内存来存放sqlite对象,ppDb将会被返回一个NULL值。

flags:作为数据库连接的额外控制的参数,可以是SQLITE_OPEN_READONLY,SQLITE_OPEN_READWRITE和SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE中的一个,用于控制数据库的打开方式,可以和SQLITE_OPEN_NOMUTEXSQLITE_OPEN_FULLMUTEXSQLITE_OPEN_SHAREDCACHE,以及SQLITE_OPEN_PRIVATECACHE结合使用,具体的详细情况可以查阅文档。

2.Sqlite3_prepare()

这个函数将sql文本转换成一个准备语句(prepared statement)对象,同时返回这个对象的指针。这个接口需要一个数据库连接指针以及一个要准备的包含SQL语句的文本。它实际上并不执行(evaluate)这个SQL语句,它仅仅为执行准备这个sql语句。

函数定义

    SQLITE_API

    int sqlite3_prepare(

    sqlite3 *db,            /* Database handle */  /* 成功打开的数据库句柄 */

    const char *zSql,       /* SQL statement, UTF-8 encoded */ /* UTF8编码的 SQL 语句 */

    int nByte,              /* Maximum length of zSql in bytes. */   /* 参数 sql 的字节数, 包含 '\0' */

    sqlite3_stmt **ppStmt,  /* OUT: Statement handle */ /* 输出:预编译语句句柄 */

    const char **pzTail     /* OUT: Pointer to unused portion of zSql */ /* 输出:指向 sql 语句中未使用的部分 */

);

SQLITE_API int sqlite3_prepare_v2(

      sqlite3 *db,            /* Database handle */

      const char *zSql,      /* SQL statement, UTF-8 encoded */

      int nByte,              /* Maximum length of zSql in bytes. */

      sqlite3_stmt **ppStmt,  /* OUT: Statement handle */

      const char **pzTail    /* OUT: Pointer to unused portion of zSql */

);

SQLITE_API int sqlite3_prepare16(

      sqlite3 *db,            /* Database handle */

      const void *zSql,      /* SQL statement, UTF-16 encoded */

      int nByte,              /* Maximum length of zSql in bytes. */

      sqlite3_stmt **ppStmt,  /* OUT: Statement handle */

      const void **pzTail    /* OUT: Pointer to unused portion of zSql */

);

SQLITE_API int sqlite3_prepare16_v2(

      sqlite3 *db,            /* Database handle */

      const void *zSql,      /* SQL statement, UTF-16 encoded */

      int nByte,              /* Maximum length of zSql in bytes. */

      sqlite3_stmt **ppStmt,  /* OUT: Statement handle */

      const void **pzTail    /* OUT: Pointer to unused portion of zSql */

);

这里只对sqlite3_prepare 的参数做下介绍:

db:数据指针。

zSql:sql语句,使用UTF-8编码。

nByte:如果nByte小于0,则函数取出zSql中从开始到第一个0终止符的内容;如果nByte不是负的,那么它就是这个函数能从zSql中读取的字节数的最大值。如果nBytes非负,zSql在第一次遇见’/000/或’u000’的时候终止.如果用户知道被传入的 sql 语句是以 '\0' 结尾的, 那么有一个更好的做法是:把nbytes的值设为该字符串的长度(包含'\0'), 这样可以避免 SQLite 复制该字符串的一份拷贝, 以提高程序的效率。

pzTail:上面提到zSql在遇见终止符或者是达到设定的nByte之后结束,假如zSql还有剩余的内容,那么这些剩余的内容被存放到pZTail中,不包括终止符。如果 pszTail 不为 NULL, 则 *pszTail 指向 sql 中第一个被传入的 SQL 语句的结尾. 该函数只编译 sql 的第一个语句, 所以 *pszTail 指向的内容则是未被编译的。

ppStmt:能够使用sqlite3_step()执行的编译好的准备语句的指针,如果错误发生,它被置为NULL,如假如输入的文本不包括sql语句。调用过程必须负责在编译好的sql语句完成使用后使用sqlite3_finalize()删除它。

说明:如果执行成功,则返回SQLITE_OK,否则返回一个错误码。推荐在现在任何的程序中都使用sqlite3_prepare_v2这个函数,sqlite3_prepare只是用于前向兼容。

准备语句(prepared statement)对象   typedef struct sqlite3_stmt sqlite3_stmt;  准备语句(prepared statement)对象一个代表一个简单SQL语句对象的实例,这个对象通常被称为“准备语句”或者“编译好的SQL语句”或者就直接称为“语句”。

语句对象的生命周期经历这样的过程:

    1.使用sqlite3_prepare_v2或相关的函数创建这个对象。

    2.使用sqlite3_bind_*()给宿主参数(host parameters)绑定值。

    3.通过调用sqlite3_step一次或多次来执行这个sql。

    4.使用sqlite3——reset()重置这个语句,然后回到第2步,这个过程做0次或多次。

    5.使用sqlite3_finalize()销毁这个

在sqlite中并没有定义sqlite3_stmt这个结构的具体内容,它只是一个抽象类型,在使用过程中一般以它的指针进行操作,而sqlite3_stmt类型的指针在实际上是一个指向Vdbe的结构体得指针。

3.sqlite3_step()

这个过程用于执行有前面sqlite3_prepare创建的准备语句。这个语句执行到结果的第一行可用的位置。继续前进到结果的第二行的话,只需再次调用sqlite3_setp()。继续调用sqlite3_setp()知道这个语句完成,那些不返回结果的语句(如:INSERT,UPDATE,或DELETE),sqlite3_step()只执行一次就返回

函数定义 :int sqlite3_step(sqlite3_stmt*);

返回值:函数的返回值基于创建sqlite3_stmt参数所使用的函数,假如是使用老版本的接口sqlite3_prepare()和sqlite3_prepare16(),返回值会是 SQLITE_BUSY, SQLITE_DONE, SQLITE_ROW, SQLITE_ERROR 或 SQLITE_MISUSE,而v2版本的接口sqlite3_prepare_v2()和sqlite3_prepare16_v2()则会同时返回这些结果码和扩展结果码。

对所有V3.6.23.1以及其前面的所有版本,需要在sqlite3_step()之后调用sqlite3_reset(),在后续的sqlite3_ step之前。如果调用sqlite3_reset重置准备语句失败,将会导致sqlite3_ step返回SQLITE_MISUSE,但是在V3. 6.23.1以后,sqlite3_step()将会自动调用sqlite3_reset。

说明:

        当一条语句被 sqlite3_prepare() 或其相关的函数预编译后, sqlite3_step() 必须被调用一次或多次来评估该预编译语句.

       该函数的详细行为依赖于由 sqlite3_prepare()(或其相关的函数) 产生的是一条怎样的预编译语句.

        函数将返回一个以下的结果来标识其执行结果:

        SQLITE_BUSY:忙碌. 数据库引擎无法锁定数据去完成其工作. 但可以多次尝试.

        SQLITE_DONE:完成. sql 语句已经被成功地执行. 在调用 sqlite_reset() 之前, 当前预编译的语句不应该被sqlite3_step() 再次调用.

        SQLITE_ROW:查询时产生了结果. 此时可以通过相关的"数据访问函数(column access functions)"来取得数据. sqlite3_step() 的再一次调用将取得下一条查询结果.

        SQLITE_ERROR:发生了错误. 此时可以通过 sqlite3_errmmsg() 取得相关的错误信息. sqlite3_step() 不能被再次调用.

        SQLITE_MISUSE:不正确的库的使用. 该函数使用不当.

4.int sqlite3_reset(sqlite3_stmt *pStmt)

sqlite3_reset用于重置一个准备语句对象到它的初始状态,然后准备被重新执行。所有sql语句变量使用sqlite3_bind*绑定值,使用sqlite3_clear_bindings重设这些绑定。Sqlite3_reset接口重置准备语句到它代码开始的时候。sqlite3_reset并不改变在准备语句上的任何绑定值,那么这里猜测,可能是语句在被执行的过程中发生了其他的改变,然后这个语句将它重置到绑定值的时候的那个状态。

它的返回值相对有些特殊。返回SQLITE_BUSY表示暂时无法执行操作,SQLITE_DONE表示操作执行完毕,SQLITE_ROW表示执行完毕并且有返回(执行select语句时)。当返回值为SQLITE_ROW时,我们需要对查询结果进行处理,SQLITE3提供sqlite3_column_*系列函数。

const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);

其中参数iCol为列的序号,从0开始。如果返回值有多行,则可以再次调用sqlite3_step函数,然后由sqlite3_column_*函数取得返回值。使用上述这些函数基本上可以完成对SQLITE3数据库的操作了(不过这里只针对text数据类型做了说明)。

5.  sqlite3_column()

这个过程从执行sqlite3_step()执行一个准备语句得到的结果集的当前行中返回一个列。每次sqlite3_step得到一个结果集的列停下后,这个过程就可以被多次调用去查询这个行的各列的值。对列操作是有多个函数,均以sqlite3_column为前缀

    const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);

    int sqlite3_column_bytes(sqlite3_stmt*, int iCol);

    int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);

    double sqlite3_column_double(sqlite3_stmt*, int iCol);

    int sqlite3_column_int(sqlite3_stmt*, int iCol);

    sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);

    const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);

    const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);

    int sqlite3_column_type(sqlite3_stmt*, int iCol);

    int sqlite3_column_numeric_type(sqlite3_stmt*, int iCol);

    sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);

说明

第一个参数为从sqlite3_prepare返回来的prepared statement对象的指针,第二参数指定这一行中的想要被返回的列的索引。最左边的一列的索引号是0,行的列数可以使用sqlite3_colum_count()获得。

(1) 得到数据行中某个列的数据

    sqlite3_column_xxx(sqlite3_stmt*, int iCol);

    在sqlite3_step返回SQLITE_ROW后,使用它得到第iCol列的数据。

    其中的xxx代表:

    blob:指向保存数据内存的指针。

    bytes, bytes16: 得到该blob类型数据的大小,或者text转换为UTF8/UTF16的字符串长度。

    double, int, int64: 数值。

    text,text16:字符串指针。

    type:该列的数据类型(SQLITE_INTEGER,SQLITE_FLOAT,SQLITE_TEXT,SQLITE_BLOB,SQLITE_NULL)

注意:如果对该列使用了不同与该列本身类型适合的数据读取方法,得到的数值将是转换过的结果。

(2) 得到数据行中某个列的数据的类型

    int sqlite3_column_type(sqlite3_stmt*, int iCol);

    返回值:SQLITE_INTEGER,SQLITE_FLOAT,SQLITE_TEXT,SQLITE_BLOB,SQLITE_NULL。

    使用的方法和sqlite3_column_xxx()函数类似。

(3)

    int sqlite3_column_count(sqlite3_stmt *pStmt); 功能:获取列数  如果过程没有返回值,如update,将返回0。

    const char *sqlite3_column_name(sqlite3_stmt*,int); 功能:获取列名 。

    const char *sqlite3_column_decltype(sqlite3_stmt *, int i); 功能:返回列数据类型。

    得到当前行中包含的数据个数  int sqlite3_data_count(sqlite3_stmt *pStmt); 如果sqlite3_step返回SQLITE_ROW,可以得到列数,否则为零。

6.sqlite3_finalize

int sqlite3_finalize(sqlite3_stmt *pStmt);这个过程销毁前面被sqlite3_prepare创建的准备语句,每个准备语句都必须使用这个函数去销毁以防止内存泄露。在空指针上调用这个函数没有什么影响,同时可以准备语句的生命周期的任一时刻调用这个函数:在语句被执行前,一次或多次调用sqlite_reset之后,或者在sqlite3_step任何调用之后不管语句是否完成执行。

示例:

    sqlite3_finalize(pStmt);

    pStmt = NULL;

7.sqlite3_close

这个过程关闭前面使用sqlite3_open打开的数据库连接,任何与这个连接相关的准备语句必须在调用这个关闭函数之前被释放

int sqlite3_close(

    sqlite3* pDB    /* 由 sqlite3_open 或基相关的函数打开的 SQLite 对象句柄 */

);

说明:

该函数用来析构 sqlite3 对象. 返回 SQLITE_OK 表示对象被成功析构, 以及所有相关的资源被成功回收应用程序必须在关闭之前 "完成(finalize)" 所有的 "预编译语句(prepared statements)", 并且关闭所有的 "二进制句柄绑定(BLOB handle)", 如果在关闭时还有未完成的预编译语句或二进制句柄, 那么函数返回 SQLITE_BUSY(5).

示例:

if(pDB != NULL)

{

    sqlite3_close(pDB);

    pDB = NULL;

  }

8.int sqlite3_exec

int sqlite3_exe(

    sqlite3* pDB,        /* sqlite3句柄 */

    const char* sql,    /* 被执行的 SQL 语句 */

    int (*callback)(void*,int,char**,char**),  /* 执行/查询回调函数 */

    void* pvoid,    /* 传递给回调函数的第一个参数 */

    char**errmsg    /* 错误输出信息 */

);

说明:

该函数用来执行若干条 SQL 语句.

该函数包裹了先前版本的 sqlite3_prepare(), sqlte3_step() 和 sqlite3_finalize() 函数, 这样, 用户就可以执行简单的代码执行多条 SQL 语句.

sqlite3_exec()接口执行多条以";"分隔的SQL语句. 如果回调函数不为 NULL, 则它对每一个行查询结果都会调用该回调函数. 如果没有回调函数被指定, sqlite3_exec() 只是简单地忽略查询结果.

当在执行该SQL语句发生错误时, 执行将发生中断, 并且后面的语句也全部被忽略. 如果 errmsg 参数不为空任何错误信息将会被写进由 sqlite3_malloc() 得到的的内存空间中, 即 errmsg 指向的内存. 为了避免内存泄漏, 应用程序应该在不需要该错误信息后立即调用 sqlite3_free() 释放该内存空间. 如果 errmsg 参数不为 NULL, 并且没有错误发生, errmsg 被设置为 NULL.

如果回调函数返回非零, sqlite3_exec() 立即中断查询, 并且不再执行后续的 SQL 语句, 也不再调用回调函数, sqlite3_exec() 将返回 SQLITE_ABORT 结束执行.

示例:

sqlite3_exec(pDB, to_utf8("delete from tablename where id=123;"), NULL, NULL, NULL);

sqlite3_exec(pDB, to_utf8("create table if not exists tablename (id integer primary key,name text);"), NULL, NULL, NULL);

sqlite3_exec(pDB, to_utf8("insert into tablename (name) values ('女孩不哭');"), NULL, NULL, NULL);

if(sqlite3_exec(pDB, to_utf8("select * from tablename;"), sqlite_callback, NULL, &pszErrMsg) != SQLITE_OK)

{

    ...

    sqlite3_free(pszErrMsg);

    pszErrMsg = NULL;

}

参阅:在 sqlite3 中使用回调函数(http://www.cnblogs.com/nbsofer/archive/2012/05/29/2523807.html)

9.int sqlite3_errcode

int sqlite3_errcode(

    sqlite3* pDB    /* SQLite3 数据库句柄 */

);

说明:

该函数返回最近一次调用 sqlite3_ API时产生的错误码.

示例:

int errcode = sqlite3_errcode(pDB);

10.const char *sqlite3_errmsg

const char *sqlite3_errmsg(

    sqlite3* pDB    /* SQLite3 数据库句柄 */

);

说明:

该函数返回与pDB数据库指针相关的错误信息, 由英语书写.

用户不必考虑内存的释放, 其由SQLite内部管理, 它也将会在下产次调用函数时被覆盖.

示例:

printf("%s\n", sqlite3_errmsg(pDB));

11.int sqlite3_key

int sqlite3_key(

    sqlite3 *db,                   /* Database to be rekeyed */    

    const void *pKey, int nKey     /* The key */

);

功能:为加密的数据库指定密码,改函数在sqlite3_open之后调用

12.int sqlite3_rekey

int sqlite3_rekey(

    sqlite3 *db,                   /* Database to be rekeyed */

    const void *pKey, int nKey     /* The new key */

);

功能:重设数据库密码,如果pKey = 0 或者 nKey = 0,这数据库不加密

13.int sqlite3_get_table

int sqlite3_get_table(

    sqlite3*,               /* An open database */

    const char *sql,       /* SQL to be executed */

    char ***resultp,       /* Result written to a char *[]  that this points to */

    int *nrow,             /* Number of result rows written here */

    int *ncolumn,          /* Number of result columns written here */

    char **errmsg          /* Error msg written here */

);

功能:查询表.

参数1(IN):数据库句柄.

参数2(IN):sql语句,以\0结尾.

参数3(OUT):查询结果.

参数4(OUT):返回行数(多少条数据).

参数5(OUT):返回列数(多少字段).

参数6(OUT):返回错误信息.

返回值:SQLITE_OK成功,房子失败见错误信息.

14.void sqlite3_free_table(char **result);

void sqlite3_free_table(char **result);

功能:释放通过sqlite3_get_table查询保存的结果数据.

参数1(IN):要释放的数据指针.

15.int sqlite3_create_function

int sqlite3_create_function(

    sqlite3 *,

    const char *zFunctionName,

    int nArg,

    int eTextRep,

    void*,

    void (*xFunc)(sqlite3_context*,int,sqlite3_value**),

    void (*xStep)(sqlite3_context*,int,sqlite3_value**),

    void (*xFinal)(sqlite3_context*)

);

功能:

const void *sqlite3_value_blob(sqlite3_value*);

int sqlite3_value_bytes(sqlite3_value*);

int sqlite3_value_bytes16(sqlite3_value*);

double sqlite3_value_double(sqlite3_value*);

int sqlite3_value_int(sqlite3_value*);

sqlite_int64 sqlite3_value_int64(sqlite3_value*);

const unsigned char *sqlite3_value_text(sqlite3_value*);

const void *sqlite3_value_text16(sqlite3_value*);

const void *sqlite3_value_text16le(sqlite3_value*);

const void *sqlite3_value_text16be(sqlite3_value*);

int sqlite3_value_type(sqlite3_value*);

int sqlite3_value_numeric_type(sqlite3_value*);

功能:类似sqlite3_column_*函数

其他:

const char *sqlite3_libversion(void);

int sqlite3_libversion_number(void);

功能:获取版本号

sqlite_int64 sqlite3_last_insert_rowid(sqlite3*);

功能:获取最后插入的行标示.

int sqlite3_changes(sqlite3*);

功能:获取最近执行的sqlite3_exec影响的行数.

int sqlite3_total_changes(sqlite3*);

功能:获取自从数据库打开后有改动的函数

void sqlite3_interrupt(sqlite3*);

功能:打断或停止数据库当前操作.

int sqlite3_complete(const char *sql);

功能:判断语句是否以分号(;)结尾

int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);

功能:设置查询忙碌时的回调处理

说明:缺省的回调函数为空,如果回调函数为空,表锁定后sqlite3_exec()执行会直接返回SQLITE_BUSY

int sqlite3_busy_timeout(sqlite3*, int ms);

功能:设置查询超时时间(毫秒)

char *sqlite3_mprintf(const char*,...);

char *sqlite3_vmprintf(const char*, va_list);

char *sqlite3_snprintf(int,char*,const char*, ...);

功能:格式化字符,需要用%q来代替%s.(主要是不用对分号'进行转义)

void *sqlite3_malloc(int);

void *sqlite3_realloc(void*, int);

void sqlite3_free(void*);

功能:内存函数

int sqlite3_set_authorizer(

    sqlite3*,

    int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),

    void *pUserData

);

功能:设置数据库授权

void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);

void *sqlite3_profile(sqlite3*,

void(*xProfile)(void*,const char*,sqlite_uint64), void*);

void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);

功能:设置执行回调函数,sqlite3_exec(),sqlite3_step() ,sqlite3_get_table()时会调用

void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);

功能:设置事务回调函数

int sqlite3_errcode(sqlite3 *db);

const char *sqlite3_errmsg(sqlite3*);

功能:获取错误码和错误消息

int sqlite3_bind_parameter_count(sqlite3_stmt*);

功能:返回需要绑定的参数数目(sql语句中问号?数量)

const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);

功能:获取绑定参数名字,?参数返回NULL

int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);

功能:获取绑定参数索引

int sqlite3_clear_bindings(sqlite3_stmt*);

功能:清除绑定的参数

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容