classic case of getting bogged down in technical stuff when learning a new language. nothing to see here...
I'm trying to enable_load_extension in tcl and get "invalid command name "dbHandle"" as an error message. The traditional SELECT name FROM sqlite_master WHERE type='table'; query at the end works perfectly, I can't see what the problem is.
Perhaps compile options? the PRAGMA compile_options; call comes back with COMPILER=msvc-1900 ENABLE_FTS3 ENABLE_RTREE THREADSAFE=1 Given that I'm not seeing SQLITE_OMIT_LOAD_EXTENSION
(https://www.sqlite.org/compile.html#omit_load_extension) I should be ok?
sqlite3_db_config with SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION
looks useful, see https://www.sqlite.org/c3ref/db_config.html and https://www.sqlite.org/c3ref/c_dbconfig_enable_fkey.html but these don't seem to be part of the tcl interface.
package require sqlite3
sqlite3 dbhandle example.db
puts [dbhandle eval {PRAGMA compile_options;}]
# $dbHandle enable_load_extension 1 ; #can't read "dbHandle": no such variable
# dbHandle enable_load_extension 1 ; #invalid command name "dbHandle"
# dbHandle enable_load_extension true ; #invalid command name "dbHandle"
# next line is fine
puts [dbhandle eval {SELECT name FROM sqlite_master WHERE type='table';}]
Related
I am attempting to run a sqlite3 command from within Go, to do a simple query (I completly understand there are other ways to access sqlite from go, but thats not the issue here)
func sqliteTest(){
cmd:=exec.Command("/usr/bin/sqlite3", " /home/chadg/Downloads/testDb.db 'select * from testTable;'")
fmt.Println("Command String:",cmd.String())
out,err:=cmd.CombinedOutput()
if err!=nil{
fmt.Println("Error Accessing Database:",err.Error(),string(out))
return
}
fmt.Println("Result Length:",len(out))
fmt.Println("Result:",string(out))
}
Running this gives me this output:
Command String: /usr/bin/sqlite3 /home/chadg/Downloads/testDb.db 'select * from testTable;'
Result Length: 0
Result:
Process finished with exit code 0
However if I run the same command by hand:
$ /usr/bin/sqlite3 /home/chadg/Downloads/testDb.db 'select * from testTable;'
testName|testValue
Have certainly run into many issues when running commands from within go, but there is always an error generated, but this time, there is no error, but the result from stdout and stderr seems to both be empty.
EDIT:
Single quotes vs double quotes doesn't change anything
cmd:=exec.Command("/usr/bin/sqlite3", " /home/chadg/Downloads/testDb.db \"select * from testTable;\"")
still returns an empty output, but works as expected from the command line.
Arguments in exec.Command should be passed as separate strings.
cmd := exec.Command("/usr/bin/sqlite3", "/home/chadg/Downloads/testDb.db", "select * from testTable;")
As for the behavior you're observing:
When sqlite3 is started non-interactively with 1 argument, it treats that as the database file name and reads the query from stdin, but cmd.CombinedOutput() closes stdin, resulting in an empty output.
I am trying to pass a .sql file into DBI::dbGetQuery, but I run into problems whenever there is comment in the first line. For example:
runs_fine.sql
SELECT * FROM mytable
does_not_work.sql
-- Some comment
SELECT * FROM mytable
Then in R:
library(odbc)
library(tidyverse)
con <- dbConnect(odbc(), "my_connection")
dbGetQuery(con, read_file("sql/runs_fine.sql")) # success
dbGetQuery(con, read_file("sql/does_not_work.sql")) # fails
Motivation: I would like to leverage the convenient sql preview function from RStudio, but this requires the first line be the following for any .sql file:
-- !preview conn=con
...which causes the dbGetQuery to fail. I suppose a workaround would be to use some sort of read.file function that can skip lines or avoid comment lines.
NOTE: If a comment line is in the middle of a .sql file, dbGetQuery succeeds as expected and avoids the appropriate commented lines.
DBMS is CHD Impala, kerberized. The return value from read_file() begins with:
"-- !preview conn=con\r\n\r\nSELECT \r\n ..."
I am discovering writing functions in TCL for Sqlite (https://github.com/pawelsalawa/sqlitestudio/wiki/ScriptingTcl).
I wanted to play a basic exemple found in the official page of sqlite(http://sqlite.org/tclsqlite.html):
db eval {SELECT * FROM MyTable ORDER BY MyID} values {
parray values
puts ""
}
I get the following error:
Error while requesting the database « -- » : invalid command name "parray"
Help is very welcome :)
SqliteStudio does not seem to fully initialise Tcl, as you would expect it from a non-embedded installation:
Using external Tcl packages or modules is not possible, because Tcl
interpreters are not initialized with "init.tcl".
See Wiki.
Background
Standard Tcl sources init.tcl, early as part of an Tcl interpreter's initialisation. init.tcl, in turn, registers a number of Tcl procs for autoloading. parray is one of those lazily acquired procs.
Ways forward
I am not familiar with SqliteStudio. Why not stick with sqlite's standard Tcl frontend, which gives you full Tcl and comes with Tcl distributions free house? But this certainly depends on your requirements.
That said, you could attempt to force-load init.tcl in SqliteStudio's embedded Tcl, but I don't know (and can't test) whether the distribution has not pruned these scripts or whether they were effectively relocated. From the top of my head (untested):
source [file join $tcl_library init.tcl]
# ...
db eval {SELECT * FROM MyTable ORDER BY MyID} values {
parray values
puts ""
}
Background: I am developing a rscript that pulls data from a mysql database, performs a logistic regression and then inserts the predictions back into the database. I want the entire system to be self contained in the script in case of database failure. This includes all mysql stored procedures that the script depends on to aggregate the data on the backend since these would be deleted in such a database failure.
Question: I'm having trouble creating a stored procedure from an R script. I am running the following:
mySQLDriver <- dbDriver("MySQL")
connect <- dbConnect(mySQLDriver, group = connection)
query <-
"
DROP PROCEDURE IF EXISTS Test.Tester;
DELIMITER //
CREATE PROCEDURE Test.Tester()
BEGIN
/***DO DATA AGGREGATION***/
END //
DELIMITER ;
"
sendQuery <- dbSendQuery(connect, query)
dbClearResult(dbListResults(connect)[[1]])
dbDisconnect(connect)
I however get the following error that seems to involve the DELIMITER change.
Error in .local(conn, statement, ...) :
could not run statement: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DELIMITER //
CREATE PROCEDURE Test.Tester()
BEGIN
/***DO DATA AGGREGATION***/
EN' at line 2
What I've Done: I have spent quite a bit of time searching for the answer, but have come up with nothing. What am I missing?
Just wanted to follow up on this string of comments. Thank you for your thoughts on this issue. I have a couple Python scripts that need to have this functionality and I began researching the same topic for Python. I found this question that indicates the answer. The question states:
"The DELIMITER command is a MySQL shell client builtin, and it's recognized only by that program (and MySQL Query Browser). It's not necessary to use DELIMITER if you execute SQL statements directly through an API.
The purpose of DELIMITER is to help you avoid ambiguity about the termination of the CREATE FUNCTION statement, when the statement itself can contain semicolon characters. This is important in the shell client, where by default a semicolon terminates an SQL statement. You need to set the statement terminator to some other character in order to submit the body of a function (or trigger or procedure)."
Hence the following code will run in R:
mySQLDriver <- dbDriver("MySQL")
connect <- dbConnect(mySQLDriver, group = connection)
query <-
"
CREATE PROCEDURE Test.Tester()
BEGIN
/***DO DATA AGGREGATION***/
END
"
sendQuery <- dbSendQuery(connect, query)
dbClearResult(dbListResults(connect)[[1]])
dbDisconnect(connect)
I submitted a simple (so I thought) query via RODBC :
ch <- odbcConnect(dsn.name, believeNRows=FALSE, rows_at_time=1)
sqlQuery(ch, "CURRENT_TIMESTAMP()")
And it threw the following error:
[1] "42000? -1 Malformed SQL Statement: Unrecognized keyword: CURRENT_TIMESTAMP\r\nStatement:CURRENT_TIMESTAMP()"
[2] "[RODBC] ERROR: Could not SQLExecDirect 'CURRENT_TIMESTAMP()'"
I thought CURRENT_TIMESTAMP() is a common SQL command and didn't expect this to not run. I had checked that the ODBC connection (RSSBus DynamicsCRM Source x64) supports CURRENT_TIMESTAMP(). My connection is OK, I was able to perform some other SQL queries.
So is there a problem with my syntax above? Or is there a list of keywords that RODBC doesn't recognise?
In the above code, first line i.e.
ch <- odbcConnect(dsn.name, believeNRows=FALSE, rows_at_time=1)
creates a connection to your ODBC data source name (dsn.name). So here ch basically stores the connection instance. The second line:
sqlQuery(ch, "CURRENT_TIMESTAMP()")
executes the SQL query on the connection i.e. ch and returns the result in a data frame. So instead of using the method CURRENT_TIMESTAMP() use complete query:
sqlQuery(ch, "SELECT CURRENT_TIMESTAMP()")
I hope this will help.