与SQLite数据库

时间:2016-10-20 16:21:52

标签: database sqlite vbscript

我正在编写一个与SQLite数据库交互的VBS程序。

此数据库包含两个表:FollowUnfollow

Follow表中,我有两列:NameJoined Name是帐户的名称,Joined是我关注此帐户的日期。

Unfollow表中,我有1列:Name Name是我取消关注的帐户的名称。

我的代码:

Dim objConn, objRecordSet, following, search_value, search_value2, search_value3

Const adOpenStatic = 3
Const adLockOptimistic = 3

Set objConn = CreateObject("ADODB.Connection")
Set objRecordSet = CreateObject("ADODB.Recordset")

'Connexion database SQLite
objConn.Open("DRIVER=SQLite3 ODBC Driver;Database=C:\Users\Quentin\Downloads\Quentin-Classementhashtags.db")

following = "toto"

'Query to look if a recording exists
objRecordSet.Open "SELECT Name FROM Follow WHERE Name = '" & following & "';", objConn, adOpenStatic, adLockOptimistic

'Travels the database to know if the following already exists
If (objRecordSet.EOF) Then
    search_value = 0
Else
    search_value = 1
End If

objRecordSet.Close

objRecordSet.Open "SELECT Name FROM Unfollow WHERE Name = '" & following & "';", objConn, adOpenStatic, adLockOptimistic

If (objRecordSet.EOF) Then
    search_value2 = 0
Else
    search_value2 = 1
End If

objRecordSet.Close

'Query to look for the recordings which date more than 20 days
objRecordSet.Open "SELECT Name FROM Follow WHERE Joined < datetime(CURRENT_DATE, '-20 days');", objConn, adOpenStatic, adLockOptimistic

If (objRecordSet.EOF) Then
    search_value3 = 0
Else
    search_value3 = 1
End If

objRecordSet.Close

'Insert into the table Follow a new line containing the following last one if it does not already exist
If search_value = 0 Then
    objRecordSet.Open "INSERT INTO Follow (Name, Joined) VALUES ('" & following & "', CURRENT_DATE);", objConn, adOpenStatic, adLockOptimistic
End If

'Insert into the table Unfollow a new line containing the following if it does not already exist and what it dates more than 20 days
If search_value2 = 0 And search_value3 = 1 Then
    objRecordSet.Open "INSERT INTO Unfollow (Name) VALUES ('" & following & "');", objConn, adOpenStatic, adLockOptimistic
End If

objConn.Close

当我想在Follow表格中添加关注时,我的代码可以正常运行。但这对第二部分不起作用:

If search_value2 = 0 And search_value3 = 1 Then
    objRecordSet.Open "INSERT INTO Unfollow (Name) VALUES ('" & following & "');", objConn, adOpenStatic, adLockOptimistic
End If

如果Unfollow表中已存在该记录,则该记录不会写入,但无论是否超过20天,都会写入该记录。

1 个答案:

答案 0 :(得分:0)

SQL查询

SELECT Name
FROM Follow
WHERE Joined < datetime(CURRENT_DATE, '-20 days')

Follow返回所有名称的日期超过20天,这意味着如果有任何,您将在Nofollow中插入指定的名称记录在Follow可追溯到目前为止,而不仅仅是具有该特定名称的记录。

你真正想要的是这样的:

INSERT INTO Nofollow
SELECT Name
FROM Follow t1
WHERE t1.Name = 'foo'
  AND t1.Joined < datetime(CURRENT_DATE, '-20 days')
  AND NOT EXISTS (SELECT 1 FROM Nofollow t2 WHERE t2.Name = t1.Name)

仅当Nofollow中存在超过20天的日期时,才会将指定的名称插入Follow

但是,您希望避免在VBScript中通过字符串连接构建查询,即 NOT 执行以下操作:

"INSERT INTO Nofollow " & _
"SELECT Name FROM Follow t1 " & _
"WHERE t1.Name='" & name & "' AND ..."
'              ^^^^^^^^^^^^^^ evil!

因为这会让你容易受到SQL injection的攻击。而是使用parameterized query(AKA准备好的声明):

name = "foo"
qry  = "INSERT INTO Nofollow " & _
       "SELECT Name FROM Follow t1 " & _
       "WHERE t1.Name=? AND t1.Joined < datetime(CURRENT_DATE, '-20 days') " & _
       "AND NOT EXISTS (SELECT 1 FROM Nofollow t2 WHERE t2.Name=t1.Name)"

db = "C:\path\to\your.db"
cs = "DRIVER=SQLite3 ODBC Driver;Database=" & db

Set cn = CreateObject("ADODB.Connection")
cn.Open cs

Set cmd = CreateObject("ADODB.Command")
Set cmd.ActiveConnection = cn
cmd.CommandText = qry

Set p = cmd.CreateParameter("@name", 200, 1, 255, name)
cmd.Parameters.Append p

cmd.Execute

cn.Close

如果要插入表格Nofollow中尚未存在的超过20天的所有名称,则需要稍微不同的查询而不使用名称参数:

qry  = "INSERT INTO Nofollow " & _
       "SELECT Name FROM Follow t1 " & _
       "WHERE t1.Joined < datetime(CURRENT_DATE, '-20 days') " & _
       "AND NOT EXISTS (SELECT 1 FROM Nofollow t2 WHERE t2.Name=t1.Name)"

db = "C:\path\to\your.db"
cs = "DRIVER=SQLite3 ODBC Driver;Database=" & db

Set cn = CreateObject("ADODB.Connection")
cn.Open cs

Set cmd = CreateObject("ADODB.Command")
Set cmd.ActiveConnection = cn
cmd.CommandText = qry

cmd.Execute

cn.Close