'获取数据，返回行数，如果=<0 为出错，可以读 ErrStr 来看什么错
'返回 saRecSetZ() 2维数组
'执行查询的结果在 saRecSetZ（ 行, 列）下标为零
' 结果第一行0为列名称,字段名字
' 数据从1开始连续
'    Dim xdb as ySQLite3 
'    Dim rs() as String 
'    Dim as Long x,y 
' xdb.Open("test.db")
' If xdb.GetSelect("SELECT * FROM sqlite_sequence ",rs()) Then
' Print UBound( rs);UBound( rs,2)
'    For y=0 To UBound( rs)
'        For x=0 To UBound(rs,2)
'            Print rs(y,x) & " , " ;
'        Next
'        Print
'    Next
' Else
'    Print "出错：" 
' End If
'SELECT * FROM test WHERE
'SELECT        字段名
'FROM          表名
'WHERE         条件
'GROUP BY      分组
'HAVING
'LIKE  'AA%'       模糊查找 
'ORDER BY   字段名   ASC|DESC     排序，ASC 升序（默认） 
'LIMIT     行数| 开始,行数  ，一般放SQL最后， 就是 MSSQL 里的 TOP ，可以是1个参数或者2个
'          1个参数，指定查询行数
'          2个参数，从第几行查询多少行，第一行为= 0 就是从0开始。
'获取新插入数据自增长的ID值
' 如："INSERT INTO Table1([中文]) VALUES('1')"
'方法1：
'     sql="SELECT last_insert_rowid() FROM Table1 LIMIT 1" 
'     SQLiteSelect( hDB,Sql,rs())
'    ID值=rs(1,0)    而 rs(0,0)的内容是 last_insert_rowid
'    如果省略 LIMIT 1 ，RS将返回所有记录的行数，但内容都相同，造成处理时间增加，浪费
'方法2：
'   ID值=sqlite3_last_insert_rowid(hDB)
'   DECLARE FUNCTION sqlite3_last_insert_rowid CDECL IMPORT "SQLITE3.DLL" ALIAS "sqlite3_last_insert_rowid" (BYVAL hDbc AS DWORD  ) AS QUAD ' sqlite3 *
'   函数不用定义，直接调用就好
Function SQLiteSelect(ByVal db as SQLite3 Ptr, ByVal sSql as String, saRecSetZ() as String) as Integer
   '获取数据，返回行数，如果=<0 为出错，可以读 ErrStr 来看什么错
   '返回 saRecSetZ() 2维数组
   '执行查询的结果在 saRecSetZ（ 行, 列）下标为零
   '结果第一行0为列名称,字段名字
   '数据从1开始连续
   'Dim xdb as ySQLite3
   'Dim rs() as String
   'Dim as Long x,y
   'xdb.Open("test.db")
   'If xdb.GetSelect("SELECT * FROM sqlite_sequence ",rs()) Then
   'Print UBound( rs);UBound( rs,2)
   'For y=0 To UBound( rs)
   'For x=0 To UBound(rs,2)
   'Print rs(y,x) & " , " ;
   'Next
   'Print
   'Next
   'Else
   'Print "出错："
   'End If
   
   Dim i as Integer
   Dim lpTable as ZString Ptr Ptr ' 返回给定表的数组指针（从列名称）
   Dim nRows as Integer         ' 返回的记录集的行数
   Dim nColumns as Integer         ' 返回的记录集的列数
   Dim lpErrorSz as ZString Ptr         ' 错误信息
   Dim zField as ZString Ptr   ' 返回给定表的字段（在lpTable数组元素）
   Dim iFields as Integer         ' 返回表返回的字段数
   Dim iRow as Integer
   Dim iCol as Integer
   Dim iResult as Integer         ' 行或错误的数量由我函数返回
   ''' 执行查询的结果在 saRecSetZ（ RowNo&, ColNo&）下标为零
   ''' 结果第一行0为列名称
   ''' 数据从1开始连续
   
   sSql = StrToUtf8(sSql) & Chr(0)
   'Declare Function sqlite3_get_table(ByVal db as sqlite3 Ptr, ByVal zSql as Const ZString Ptr,
   'ByVal pazResult as ZString Ptr Ptr Ptr, ByVal pnRow as Long Ptr, ByVal pnColumn as Long Ptr, ByVal pzErrmsg as ZString Ptr Ptr) as Long
   
   If sqlite3_get_table(DB, ByVal StrPtr(sSQL), @lpTable, @nRows, @nColumns, @lpErrorSz) = 0 Then '成功
      
      If nRows = 0 Then Goto Bail
      '第2个参数是 sql 语句，跟 sqlite3_exec 里的 sql 是一样的。是一个很普通的以/0结尾的char *字符串。
      '第3个参数是查询结果，它依然一维数组（不要以为是二维数组，更不要以为是三维数组）。
      '它内存布局是：第一行是字段名称，后面是紧接着是每个字段的值。下面用例子来说事。
      '第4个参数是查询出多少条记录（即查出多少行）。
      '第5个参数是多少个字段（多少列）。
      '第6个参数是错误信息，跟前面一样，这里不多说了。
      iFields = ((nRows + 1) * nColumns) -1
      ReDim saRecSetZ(nRows, nColumns -1)
      
      For i = 0 To iFields
         'zField = *lpTable[i]
         saRecSetZ(iRow, iCol) = *lpTable[i]
         iCol += 1 : If iCol = nColumns Then iCol = 0
         If (i + 1) Mod nColumns = 0 Then iRow += 1
      Next i
   Else
      iResult = -1 : Goto Bail
      'ErrStr = *sqlite3_errmsg(DB)
      Function = -1
   End If
   
   Function = nRows
Bail : 
   'declare sub sqlite3_free_table(byval result as zstring ptr ptr)
   sqlite3_free_table lpTable  '不论数据库查询是否成功，都释放 char** 查询结果
   
End Function