Что нового

Добавление массива в SQLite

vovsla

Осваивающий
Сообщения
607
Репутация
36
Давно видел на форуме тему в которой было реализовано добавление массива в SQLite не через For - next, а сразу целиком всего массива одним запросом _SQLite_Exec. Никак не могу найти. Киньте ссылочку пожалуйста
 
Автор
V

vovsla

Осваивающий
Сообщения
607
Репутация
36
Ответ 4 подразумевает именно ту схему которую я и имел в виду под for - next
Код:
_SQLite_Exec(-1, 'BEGIN;')
For $i = 1 To 1000
	_SQLite_Exec(-1, "INSERT INTO Table1 VALUES ('"&$i&"');")
Next
_SQLite_Exec(-1, 'COMMIT;')


было более эффективное решение
 

ra4o

AutoIT Гуру
Сообщения
1,165
Репутация
246
Вот 4-й вариант ответа
Код:
;~ 4. еще быстрее
$iTimer = TimerInit()
$sExec = 'BEGIN;DROP TABLE IF EXISTS TEST;CREATE TABLE TEST([NUM_TEST] INTEGER);'
For $i = 1 To 10000
    $sExec &= 'INSERT INTO TEST VALUES (' & $i & ');'
Next
$sExec &= 'COMMIT;'
$hDB = _SQLite_Open($sFileDB)
_SQLite_Exec($hDB, $sExec)
_SQLite_Close($hDB)
ConsoleWrite(StringFormat('4.\t%.2f sec\n', TimerDiff($iTimer) / 1000))

_SQLite_Shutdown()
В цикле формируется строка запроса, сам запрос выполняется 1 раз после цикла, по - этому и скорость самая высокая.
 
Автор
V

vovsla

Осваивающий
Сообщения
607
Репутация
36
Я понял какой ответ, просто думал что это примерно то же самое. После замеров оказалось что это в 100 раз быстрее
 
Автор
V

vovsla

Осваивающий
Сообщения
607
Репутация
36
При предложенном способе появляются проблемы.
Код:
$SQLExec='BEGIN;'
$SQLExec&=INSERT INTO Table1
$SQLExec&=INSERT INTO Table1
$SQLExec&=INSERT INTO Table1

$SQLExec&=INSERT INTO Table2

$SQLExec&='COMMIT;'
_SQLite_Exec($DMTDBSQL, $SQLExec)


Если в Table1 значения не добавлены по ошибке уникальности, то в Table2 значения тоже не будут добавлены не смотря на отсутствие ошибок


Кроме этого, и при этой схеме в Table2 ничего не будет добавлено. Значения добавятся в Table2 только если закоментить все строки с $SQLExec
Код:
$SQLExec='BEGIN;'
$SQLExec&=INSERT INTO Table1
$SQLExec&=INSERT INTO Table1
$SQLExec&=INSERT INTO Table1
$SQLExec&='COMMIT;'
_SQLite_Exec($DMTDBSQL, $SQLExec)

_SQLite_Exec($DMTDBSQL, 'INSERT INTO Table2')
 
Автор
V

vovsla

Осваивающий
Сообщения
607
Репутация
36
Сделал себе функцию для быстрой записи массивов в SQL, может кому пригодиться...

Код:
$TMPEDB=_SQLite_Open()
_SQLite_Exec($TMPEDB, "CREATE TABLE IF NOT EXISTS TMPTable (ClassnameNN VARCHAR, PosX NUMERIC, PosY NUMERIC, Width NUMERIC, Height NUMERIC, Text VARCHAR );")
SQLiteWriteArray($TMPEDB, 'INSERT INTO TMPTable (ClassnameNN, PosX, PosY, Width, Height, Text)', $ElementsArr, 1) ; пример

Func SQLiteWriteArray($DBHanle, $ExecString, $Array, $StartRow=0)
	If Not IsArray($Array) Then
		Msg(16, 'Ошибка получения массива')
		Return False
	EndIf

	$Exec="BEGIN;"
	If UBound($Array, 0)=1 Then
		For $ArrRowNum = $StartRow To UBound($Array)-1
			$Exec&=$ExecString&"' VALUES ('"&$Array[$ArrRowNum]&"');'"
		Next
	Else
		For $ArrRowNum = $StartRow To UBound($Array)-1
			$StringValues="'"
			For $ArrColNum = 0 To UBound($Array, 2)-1
				$StringValues&=$Array[$ArrRowNum][$ArrColNum]&"', '"
			Next
			$StringValues=StringRegExpReplace($StringValues, ", '$", ');')
			$Exec&=$ExecString&' VALUES ('&$StringValues
		Next
	EndIf
	$Exec&="COMMIT;"

	_SQLite_Exec($DBHanle, $Exec)
EndFunc

Func Msg($Flag, $Text, $Timeout=0)
	TT()
	If Not IsDeclared('TitleGlobal') Then Assign('TitleGlobal', '')
	If Not IsDeclared('Form1') Then
		Return MsgBox(262144+$Flag, $TitleGlobal, $Text, $Timeout)
	Else
		Return MsgBox($Flag, Eval('TitleGlobal'), $Text, $Timeout, Eval('Form1'))
	EndIf
EndFunc

Func TT($Flag=0, $Text='', $XCord=@DesktopWidth/2, $YCord=@DesktopHeight/2)
	If Not IsDeclared('TitleGlobal') Then Assign('TitleGlobal', '')
	ToolTip($Text, $XCord, $YCord, Eval('TitleGlobal'), $Flag, 2)
EndFunc
 
Верх