Using GB.Subst for data base "sqlite3"

Post

Posted
Rating:
#1 (In Topic #1865)
Avatar
Enthusiast
GrayGhost is in the usergroup ‘Enthusiast’
I have been using Sqlite and making up my own string of data to quiry and update the files and it work ok …
But according to the tutorial , I shoud be using db.subst() to create the inquires of the data base.
That some time work , but not with all inquires.
I can not get this to work, I have tried all different permetaions of ' and " and ` with no success and always get similuar errors

Are there newer instruction somewere ?    I would like to do it correctly so I may switch to different databases and have the program work.
Using the deleat command work OK :

   $con.Exec(DB.Subst("delete from [&1] where  `&2`  = &3 ", sFileName, sFileField, sFileIndex))

The above works just fine … What am I doing wrong ???

Screenshot_2025-11-04_13-01-34.png
Online now: No Back to the top

Post

Posted
Rating:
#2
Trainee
From the wiki: "These arguments are quoted according to the underlying database".

I think you need to remove the quotation marks from the third argument

$con.Exec(db.subst("update [&1] set &2 where &3 = &4", sFileName, saCommand, sBkAccColumn, sFileIndex))

Greetings, Harpo.
 
Online now: No Back to the top

Post

Posted
Rating:
#3
Avatar
Enthusiast
GrayGhost is in the usergroup ‘Enthusiast’
I have tried that ... and every other combination ... always the same results
Online now: No Back to the top

Post

Posted
Rating:
#4
Avatar
Expert
Quincunxian is in the usergroup ‘Expert’
Hi GrayGhost,
Displaying the query as a message can often help you understand where the error is.  

Message(DB.Subst("delete from [&1] where  `&2`  = &3 ", sFileName, sFileField, sFileIndex))
(At a glance, I suspect that the apostrophes should be around &3 instead of &2 - apostrophes are required around literal string data not field names. )

I don't use DB.Subst as I've found it makes the line of query code harder to read and fault find.
I know that the tutorial states that this is for security reasons but SQLite is not really secure and that advice was more for MYSQL and PostGres which have far higher inbuilt security.


If you want to make the function work with different attributes, try something like this.

Code

Public Sub DeleteRecordByIndex(InTable as string, InField as string, InIndex as Varient )

 Dim $Query as string = "DELETE FROM " & InTable & " WHERE(" & InField & "=" & InIndex & ")"  

DB.Exec($Query)

End

Provided your field types are the same, this should work with any table of those types.

Note# If you write query SQL commands in upper case and variables in Camel case then it can also help you quickly review and debug statements. 


Edit: Just noticed that you have used the variable 'DB' as your connection
DB is actually a Gambas class 'representing the first opened database'.  I've often used more that one physical database in an application and you can easily get muddled by using this as the default.
Just be aware of that as you start doing more complex database stuff.


 

Cheers - Quin.
I code therefore I am
Online now: No Back to the top

Post

Posted
Rating:
#5
Trainee
I had only looked at the function's syntax.
Assuming it's an update statement, the string should be:

 $con.Exec(db.subst("UPDATE &1 SET &2 = &3 WHERE &4 = &5", TableName, FieldToUpdate, NewValue, FileIndex, ValueIndex))

 
Online now: No Back to the top

Post

Posted
Rating:
#6
Avatar
Administrator
gbWilly is in the usergroup ‘unknown’

GrayGhost said

I have been using Sqlite and making up my own string of data to quiry and update the files and it work ok …
But according to the tutorial , I shoud be using db.subst() to create the inquires of the data base.
That some time work , but not with all inquires.
I can not get this to work, I have tried all different permetaions of ' and " and ` with no success and always get similuar errors

Are there newer instruction somewere ?    I would like to do it correctly so I may switch to different databases and have the program work.
Using the deleat command work OK :

   $con.Exec(DB.Subst("delete from [&1] where  `&2`  = &3 ", sFileName, sFileField, sFileIndex))

The above works just fine … What am I doing wrong ???

To answer your question: "Listening to a tutorial telling you what you should do, when you already had a working solution.", I would say is what you are doing wrong ;):lol:

Now, on to the solution. I can't help with with db.subst as I never ever used is. It got introduced into gambas somewhere along the road when I had my milage in using queries with Gambas.
So, you kind of don't pay attention to what's new but doesn't add anything to what you already do. I simpy use the regular Subst (and always have) and that has always worked for me, so, why change a winning team, right! :thumbs:

I believe, and correct me if I'm wrong, that db.subst is trying to abstract the query a bit more from the underlying database used, so it works a bit different.
Since I only ever use mariadb and do often use very mariadb specific sql queries, regular Subt does the job just fine. (so you have: gb.subst gb.db.subst and gb.db2.subst)
Below a simple example from one of my applications where I use the selection made in a ComboBox to filter content using regular Subst.

example.png


 

gbWilly
- Gambas Dutch translator
- Gambas wiki content contributor
- Gambas debian/ubuntu package recipe contributor
- GambOS, a distro for learning Gambas and more…
- Gambas3 Debian/Ubuntu repositories


… there is always a Catch if things go wrong!
Online now: No Back to the top

Post

Posted
Rating:
#7
Avatar
Enthusiast
GrayGhost is in the usergroup ‘Enthusiast’
as I said in my original post .. I have been able to create my own strings to make all the functions work.
Just trying to conform to Gambas standared for future updates to the Gambas language by following the correct programing form .
Online now: No Back to the top

Post

Posted
Rating:
#8
Avatar
Administrator
gbWilly is in the usergroup ‘unknown’
The topic should read "using gb.db.subst" as gb.subst is the regular Subst and not the database variant.

gbWilly
- Gambas Dutch translator
- Gambas wiki content contributor
- Gambas debian/ubuntu package recipe contributor
- GambOS, a distro for learning Gambas and more…
- Gambas3 Debian/Ubuntu repositories


… there is always a Catch if things go wrong!
Online now: No Back to the top

Post

Posted
Rating:
#9
Avatar
Enthusiast
GrayGhost is in the usergroup ‘Enthusiast’
Post Marker #12812
The topic should read "using gb.db.subst" as gb.subst is the regular Subst and not the database variant.

I did not know there was another ,  will give it a try … thanks

Last edit: by GrayGhost

Online now: No Back to the top

Post

Posted
Rating:
#10
Avatar
Enthusiast
GrayGhost is in the usergroup ‘Enthusiast’
where do I find gb.db.subst ????
Online now: No Back to the top

Post

Posted
Rating:
#11
Avatar
Administrator
gbWilly is in the usergroup ‘unknown’

GrayGhost said

where do I find gb.db.subst ????

gb = default gambas language. no components (gb.subst)
gb.db = gambas component gb.db (
gb.db.subst)


 

gbWilly
- Gambas Dutch translator
- Gambas wiki content contributor
- Gambas debian/ubuntu package recipe contributor
- GambOS, a distro for learning Gambas and more…
- Gambas3 Debian/Ubuntu repositories


… there is always a Catch if things go wrong!
Online now: No Back to the top

Post

Posted
Rating:
#12
Avatar
Administrator
gbWilly is in the usergroup ‘unknown’

GrayGhost said

as I said in my original post .. I have been able to create my own strings to make all the functions work.
Just trying to conform to Gambas standared for future updates to the Gambas language by following the correct programing form .

Then I'll have to write a page on the wiki using regular Subst for databases, just to confuse your concept of 'the correct programming form'  :ninja: :P  :lol:

gbWilly
- Gambas Dutch translator
- Gambas wiki content contributor
- Gambas debian/ubuntu package recipe contributor
- GambOS, a distro for learning Gambas and more…
- Gambas3 Debian/Ubuntu repositories


… there is always a Catch if things go wrong!
Online now: No Back to the top

Post

Posted
Rating:
Item has a rating of 5 (Liked by sholzy)
#13
Avatar
Enthusiast
GrayGhost is in the usergroup ‘Enthusiast’
So since db.subst does not seem to work with sqlite3 ... I will just continue to make up my own strings to use sqlite.
Online now: No Back to the top

Post

Posted
Rating:
#14
Avatar
Enthusiast
PJBlack is in the usergroup ‘Enthusiast’
try building your connection object …

Code

Public/Privat con as connection

public/private sub/function blahblubb()

con = new connection

with con
.type = "sqlite"
.host = [path to database]
.name = [the database himself]
try .close
.open
end with

then build your query …

Code

Dim q,t,w,v as string

t = [table]
w = [searchfield]
v = [searchvalue]

q=con.subst("delete from &1 where &2 = &3;", t,w,v)

not tested but should work …
 

Last edit: by PJBlack

Online now: No Back to the top

Post

Posted
Rating:
#15
Avatar
Enthusiast
GrayGhost is in the usergroup ‘Enthusiast’
Yes Delete and Select  are the two  command's that works correctly

this also works"

   Rs = $con.Exec(db.Subst("select * from [&1] where '&2' = &3", sFileName, sFileColumn, sFileIndex))


but not any command that used a string of values.

Last edit: by GrayGhost

Online now: No Back to the top

Post

Posted
Rating:
Item has a rating of 5 (Liked by gbWilly)
#16
Avatar
Enthusiast
Gianluigi is in the usergroup ‘Enthusiast’
Hi @GrayGost
I put together an old test and added Edit.
Since you're planning on using DB, and I agree with your thoughts on security, you could use that instead of Subst; once you understand it, it's easier to use.
The fact that Subst in gb.db2 doesn't work could be a bug; I don't have time now, but I'll investigate.
Use DB.Debug to see what the queries are doing.
Create a connection (see images) to see database
It looks like the Date function has a bug…

I'm attaching the project and hope it's helpful.
Attachment

test-db-0.0.2.tar.gz

conn1.png conn2.png conn3.png Schermata del 2025-11-05 16-00-58.png
Online now: No Back to the top

Post

Posted
Rating:
#17
Avatar
Administrator
gbWilly is in the usergroup ‘unknown’

Gianluigi said

It looks like the Date function has a bug…

It's fixed  :lol:  according to the post on the mailing list.
Thanks for being stubborn  :thumbs:

gbWilly
- Gambas Dutch translator
- Gambas wiki content contributor
- Gambas debian/ubuntu package recipe contributor
- GambOS, a distro for learning Gambas and more…
- Gambas3 Debian/Ubuntu repositories


… there is always a Catch if things go wrong!
Online now: No Back to the top

Post

Posted
Rating:
#18
Avatar
Enthusiast
Gianluigi is in the usergroup ‘Enthusiast’

gbWilly said

It's fixed    according to the post on the mailing list.
Thanks for being stubborn  

 :lol:

 :goodbye:
Online now: No Back to the top

Post

Posted
Rating:
#19
Avatar
Enthusiast
GrayGhost is in the usergroup ‘Enthusiast’
I finally got it to work using subst … I guess db.subst in broken   :(


   $con.Exec(Subst("update [&1] set &2 where &3 = '&4'", sFileName, saCommand, sBkAccColumn, sFileIndex))

 :wub:

Last edit: by GrayGhost

Online now: No Back to the top

Post

Posted
Rating:
#20
Avatar
Enthusiast
GrayGhost is in the usergroup ‘Enthusiast’
 Gianluigi posted:

"The fact that Subst in gb.db2 doesn't work could be a bug; I don't have time now, but I'll investigate.
Use DB.Debug to see what the queries are doing."

I have tested with Debug and found that subst USES gb.db2.subst
   $con.Exec(Subst("update [&1] set &2 where &3 = '&4'", sFileName, saCommand, sBkAccColumn, sFileIndex))

Debug outputs this :
Screenshot_2025-11-07_12-37-16.png
So it appares that is it is not nessary to use db.subst …. BUT just use  subset  :)
Online now: No Back to the top

Post

Posted
Rating:
#21
Avatar
Enthusiast
Gianluigi is in the usergroup ‘Enthusiast’
However, sticking with the example I posted, if you want to achieve the same result as Edit with Subst and Exec, the string should be combined something like this:
Keep in mind that without injection protection, the SQL string should look like this:
UPDATE table_name SET column1 = value1, column2 = value2, … WHERE condition;

So, corresponding code could be:

Code (gambas)

Public Sub myEdit(iParameter As Integer, Optional sName As String, sSurname As String, hDate As Date)

  Dim hResult As Result
  Dim sTable As String = "tuser"
  Dim sCriteria As String
  Dim aColumns As String[] = ["uskey", "usnam", "ussur", "usdat"]

  db.Debug = True
  OpenDB()
  sCriteria = DB.Subst("update [&1] set '&2' = &3, '&4' = &5 where '&6' = &7", sTable, aColumns[1], sName, aColumns[3], hdate, aColumns[0], iParameter)
  $hConn.Begin
  hResult = $hConn.Exec(sCriteria)
  ' or
  ' hResult = DB.Exec(sCriteria)
  ' and without --->  hResult.Update
  $hConn.Commit
 
Catch
  $hConn.Rollback
  Print "#ERROR! "; Error.Text; " - "; Error.Where
  $hConn.Close
End


This is sample code, and obviously we need to find a better way to handle it…  :$
So, no bugs, Exec and Subst work as expected.

 :goodbye:
Online now: No Back to the top

Post

Posted
Rating:
#22
Avatar
Enthusiast
GrayGhost is in the usergroup ‘Enthusiast’
From my testing … don't use db.subst()  ….. just use subst() .
db.subst() gives an error with some data strings. 
Online now: No Back to the top

Post

Posted
Rating:
#23
Avatar
Enthusiast
Gianluigi is in the usergroup ‘Enthusiast’

GrayGhost said

From my testing … don't use db.subst()  ….. just use subst() .
db.subst() gives an error with some data strings. 

This is an answer the big boss gave me a while back:
"But if you omit to use Connection.Subst(), your code is utterly wrong,
as it introduces a possible SQL injection.
Regards,
Benoît Minisini"
And if he says so…

I'm attaching a specific project that demonstrates the proper functioning of connection.subst. Now you have the opportunity to prove your point, and I'm sorry if I don't take your word for it.

DB is a "superstructure" that Gambas provides. Many people don't use it, thinking (wrongly) that it slows down the database. I could also demonstrate that, in some cases, Gambas speeds up the database.

Note: Even if you can't see it, once the project is launched, the IDE contains the database folder (if you want to see it, you have to restart the IDE). You can create the connection, as shown in the images above, so you can see the database directly within the IDE.

 :goodbye:
Attachment

DBSubstTest-0.0.1.tar.gz

Online now: No Back to the top

Post

Posted
Rating:
#24
Avatar
Enthusiast
GrayGhost is in the usergroup ‘Enthusiast’
Gianluigi
Thanks for the help ….. this is why I started this thread …. to learn the correct way to do it.
I am rewriting my file handling to conform to the proper syntax.
It turns out to be even simpler and less progaming do it this way.  :):wub:

Public Sub InsertNewRecord(sFileName As String)
   Dim sNew As New String[]
   For Each obj As Object In RS.Fields    ' This assenbles the File column names it to A string[ ]
      sNew.Push(obj.Name)
   Next
sNew[0] = "newAcc" & Str(Rand(20, 99))
   $con.Exec(db.Subst("INSERT INTO [&1] VALUES   (&2, &3, &4, &5, &6, &7,&8, &9)", sFileName, sNew[0], sNew[1], sNew[2], sNew[3], sNew[4], sNew[5], sNew[6], sNew[7]))
End
Online now: No Back to the top

Post

Posted
Rating:
Item has a rating of 5 (Liked by gbWilly)
#25
Avatar
Enthusiast
Gianluigi is in the usergroup ‘Enthusiast’
I don't know how to explain it to you and I'll leave that task to those more experienced than me.
I'm a very amateur "programmer," and since I have no professional experience, I rely on those more experienced than me.
Fortunately, Minisini has provided us with the DB class, which, behind the scenes, transparently makes our queries secure and correct on any database.
Professionals like @gb.Willy can easily do without it because they know how to use queries correctly.
If the DB class doesn't always produce errors (?) when its syntax isn't respected, I think it's due to the risk of inoculation, but I'm not sure because I don't know how it works.
I just know that there's a lot of work behind it, and I'm happy it exists.
If I were you, I'd try to focus on Find and Edit. I've only used Delete for a few examples, but it's always a good idea to keep track of what's been done, and rather than removing an entire piece of information, I prefer to add columns to the table that tell me whether the information is current or not, who changed the state, and when.
Beyond that, I'd focus on Begin, Commit, Rollback, Create, Open, Close, constants, and properties.
As I said, I don't know what else to say.
 :goodbye:
Online now: No Back to the top
1 guest and 0 members have just viewed this.