根据the docs,
某些编译指示在SQL编译阶段生效,而不是执行阶段。这意味着如果使用C语言sqlite3_prepare(),sqlite3_step(),sqlite3_finalize()API(或包装器接口中的类似API),pragma可以在sqlite3_prepare()调用期间运行,而不是在sqlite3_step()调用期间作为普通SQL运行陈述呢。或者pragma可能在sqlite3_step()期间运行,就像普通的SQL语句一样。 pragma在sqlite3_prepare()或sqlite3_step()期间是否运行取决于pragma和SQLite的特定版本。
最后声明中的信息未在特定编译指示的文档中给出。假设我仍然有兴趣找到它,大概我要看源头。但到底在哪里?
答案 0 :(得分:1)
解析时执行implemented by the underlying VFS的所有编译指示。 (但是在VFS中没有实现任何预定义的编译指示。)
否则,找出的最简单方法是在生成的look pragma中virtual machine instructions。 一些pragma在VDBE代码中没有做任何事情,这意味着它们在解析时完全执行(并且EXPLAIN不会阻止它):
> EXPLAIN PRAGMA page_size = 16384; addr opcode p1 p2 p3 p4 p5 comment ---- ------------- ---- ---- ---- ------------- -- ------------- 0 Init 0 1 0 00 Start at 1 1 Halt 0 0 0 00
但请注意,未知的pragma只是被忽略了:
> EXPLAIN PRAGMA give_me_lots_of_money; addr opcode p1 p2 p3 p4 p5 comment ---- ------------- ---- ---- ---- ------------- -- ------------- 0 Init 0 1 0 00 Start at 1 1 Halt 0 0 0 00
许多只返回值的pragma在解析时生成具有当前值的代码:
> EXPLAIN PRAGMA page_size; addr opcode p1 p2 p3 p4 p5 comment ---- ------------- ---- ---- ---- ------------- -- ------------- 0 Init 0 1 0 00 Start at 1 1 Int64 0 1 0 16384 00 r[1]=16384 2 ResultRow 1 1 0 00 output=r[1] 3 Halt 0 0 0 00
但是一些pragma在执行时会查找值:
> EXPLAIN PRAGMA user_version; addr opcode p1 p2 p3 p4 p5 comment ---- ------------- ---- ---- ---- ------------- -- ------------- 0 Init 0 1 0 00 Start at 1 1 Transaction 0 0 0 00 2 ReadCookie 0 1 6 00 3 ResultRow 1 1 0 00 output=r[1] 4 Halt 0 0 0 00
可以使用VDBE代码实现一些编译指示:
> EXPLAIN PRAGMA foreign_key_check; addr opcode p1 p2 p3 p4 p5 comment ---- ------------- ---- ---- ---- ------------- -- ------------- 0 Init 0 15 0 00 Start at 15 1 OpenRead 0 2 0 2 00 root=2 iDb=0; MyTable 2 String8 0 3 0 MyTable 00 r[3]='MyTable' 3 OpenRead 1 3 0 k(2,,) 00 root=3 iDb=0 4 Rewind 0 14 0 00 5 Column 0 1 8 00 r[8]=MyTable.Parent 6 IsNull 8 13 0 00 if r[8]==NULL goto 13 7 MakeRecord 8 1 7 A 00 r[7]=mkrec(r[8]) 8 Found 1 13 7 0 00 key=r[7] 9 Rowid 0 4 0 00 r[4]=rowid 10 String8 0 5 0 MyTable 00 r[5]='MyTable' 11 Integer 0 6 0 00 r[6]=0 12 ResultRow 3 4 0 00 output=r[3..6] 13 Next 0 5 0 00 14 Halt 0 0 0 00 15 Transaction 0 0 3 0 01 usesStmtJournal=0 16 Goto 0 1 0 00
pragma(例如,default_cache_size
)在解析和执行时都执行;这通常适用于记录在数据库文件中的值(此类写入只能在事务中完成)。
所以最安全的方法是查看sqlite3Pragma
文件中的src/pragma.c
函数。