Using params in a sqlite INSERT statement in Smart Mobile Studio? - smart-mobile-studio

I have created the following database
SqlResult := fDataBase.Exec("CREATE TABLE workstations (workstation string, location string, userId string);");
How do you use params in a sqlite INSERT statement.
For example, I assume it would be something as such
FDatabase.Exec("INSERT INTO workstations values(?,?,?);", [AWorkstation, ALocation, AUserId]);
However, Exec only takes a string........so do I have to actually build out the whole string to include the params?
FDatabase.Exec("INSERT INTO workstations values( + AWorkstation + ',' + ALocation + ',' + AUserId +');" );
reason I ask, is that the
TSQLiteDatabase has a CreateStatement function that returns a
TSQLiteStatement class
which has a SQL & Params property
and the following methods
prepare
execute
release
do I instead of calling the databases exec, i instead do a createstatement, assign sql and params, and then execute ?
e.g.
stm:= fDatabase.CreateStatement;
stm.SQL:= ?
stm.Params:= ?
stm.execute;
i have even tried
FDatabase.Exec('INSERT INTO workstations (workstation, location, userid) values(' + AWorkstation + ',' + ALocation + ',' + AUserId +');');
If I hardcode the values, this works
FDatabase.Exec("INSERT INTO workstations (workstation, location, userid) values('WS0202', 'Maintenance', 'jdoe');");
but, i need to be able to use params
also tried it with a format function and still doesn't work
FDatabase.Exec(Format("INSERT INTO workstations (workstation, location, userid) values(%s ,%s, %s );", [AWorkstation, ALocation, AUserId]));

FDatabase.Exec(Format("INSERT INTO workstations (workstation, location, userid) values('%s' ,'%s', '%s');", [AWorkstation, ALocation, AUserId]));

Related

Laravel Migration: Combine multiple values in a new colum

i'm trying to make a migration using Laravel. The idea is to get the values of columns 'code' and 'id' in different tables, and merge them into a column 'name' with '-' separators.
So in part it is a SQL problem.
Currently i'm trying something like this.
First migration to create the new column 'name'
public function up()
{
Schema::table('work_order', function (Blueprint $table) {
$table->string('name')->nullable();
});
}
(works just fine)
And second migration to populate the new column with values
class AlterColumnNameWorkOrder extends Migration
{
public function up()
{
$company_code = DB::statement("SELECT code FROM company");
$campaign_code = DB::statement("SELECT code FROM campaign");
$work_order_number = DB::statement("SELECT id FROM work_order");
DB::statement("UPDATE work_order SET name = $company_code + '-' + $campaign_code + '-' + $work_order_number");
}
and i'm getting this error
SQLSTATE[22P02]: Invalid text representation: 7 ERROR: invalid input syntax for integer: "-"
LINE 1: UPDATE work_order SET name = 1 + '-' + 1 + '-' + 1
I'm thinking that i'm not getting the values but the index instead.
UPDATE: I solved the problem by replacing + for ||. But now in column 'name' all my values are "1-1-1". The values are not being represented. What am i missing?
UPDATE2: I noticed that i was defining an unnecessary variable $work_order_number. As it belongs to the same table to be updated. So I removed it and put the field "id" directly in the statement.
DB::statement("UPDATE work_order SET name = $company_code || '-' || $campaign_code || '-' || id");
Now the third value is shown correctly. And this reduces my problem to getting values from another table into an column.
First of all, you shouldn't use migrations to populate the database. Read the documentation about seeds.
Also, i think your select query is wrong. Isn't you missing a where clause?
Run php artisan migrate to migrate your database, then create a new seed, and add this to the run method:
$company_code = DB::table('company')->select('code')->where('id', some_id)->first()->code;
$campaing_code = DB::table('campaing')->select('code')->where('id', some_id)->first()->code;
$work_order_number = DB::table('work_number')->select('id')->where('id', some_id)->first()->id;
$sql = "UPDATE work_order SET name = concat('{$company_code}', '-', '{$campaign_code}', '-', '{$work_order_number}');
DB::statement(DB::raw($sql));
Now, just run php artisan db:seed --class=YourSeedClassName and it should work.

How to pass in parameters to a SQL statement in Python

I have a Python script that is calling a function that executes a SQL select statement but I keep getting errors that the Token ? was not valid. How do I pass in variables so that they work with the SQL statement? Here is my code:
def get_jde_udc_info(connection,product_code,userCode,librTable):
c1=connection.cursor()
length=c1.execute("select dtcdl, dtcnum from ?",(librTable) + " where dtsy=?",(product_code) + " and dtrt=?",(userCode))
length=c1.fetchall() # <-- Using the .fetchone method from the Python cursor class that will return a single record or None if no more rows are available
print(length)
Here is the function call in my script:
get_jde_udc_info(connection,"41","s1","testctl.f0004")
I like to use %
Like:
"SELECT field1, field2 FROM %s WHERE email = '%s'" % ('table', 'johndoe#gmail.com')

Performance of an SQL query for finding users in database

I am developing an application and I am using Spring Data JPA for database manipulation.
I am implementing a feature for finding friends with a searchbar. The way it is supposed to work is that when you enter some characters, a search is performed in the database to find and display 10 users that match the characters (the first name starts with it, the last name starts with it and it also should work if someone enters the full name).
I have written the code and it works the following way:
#Query(nativeQuery = true,
value="SELECT * FROM users u WHERE (" +
"UPPER(first_name) like CONCAT(UPPER(:query),'%') OR " +
"UPPER(last_name) like CONCAT(UPPER(:query),'%') OR " +
"UPPER(CONCAT(first_name,' ', last_name)) like CONCAT(UPPER(:query),'%')" +
") LIMIT 10")
List<User> findByQueryLikeName(#Param("query") String query);
However, when I look at this query it really seems like it might not be the best performance-wise. I do not have a lot of knowledge about sql performance, but I think that because it combines 3 where statements with an OR operator, and also uses some functions like UPPER and CONCAT a lot. I am using PostgreSQL.
Can you please assess if this kind of query is going to perform well on a big number of records? Can you try and explain why / why not? Do you have any tips on how to improve it?
Thanks a lot!
I would rewrite the query like this:
SELECT * FROM users u
WHERE concat(' ', u.first_name,' ', u.last_name) ILIKE ' ' || :query || '%';
You'd have to create a trigram index to support this:
CREATE EXTENSION pg_trgm;
CREATE INDEX ON users USING gin
(concat(' ', u.first_name,' ', u.last_name) gin_trgm_ops);
As pointed out in comments it's probably so slow because you are using functions in the WHERE clause:
https://www.mssqltips.com/sqlservertip/1236/avoid-sql-server-functions-in-the-where-clause-for-performance/
Alternatively you could add to your entity another field fullName and update it in setFirstName() and setLastName() like this:
void setFirstName(String first){
this.fullName = first.toUpperCase() + " " + this.lastName.toUpperCase(); //TODO handle nulls
}
Then you could query by that fullName, which would be already uppercased, then uppercase you search string in java and have a simple like query:
public List<User> findByFullnameContaining(String searchText, Pageable pageable);

Pyodbc and Access with query parameter that contains a period

I recently found a bug with some Access SQL queries that I can't seem to track down. I have a fairly straightforward SQL query that I use to retrieve data from an access database that's "managed" in an older application (ie the data is already in the database and I have no real control over what's in there).
import pyodbc
MDB = '******.MDB'
DRV = '{Microsoft Access Driver (*.mdb)}'
PWD = ''
con = pyodbc.connect('DRIVER={};DBQ={};PWD={}'.format(DRV, MDB, PWD))
sql = ('SELECT Estim.PartNo, Estim.Descrip, Estim.CustCode, Estim.User_Text1, Estim.Revision, ' +
'Estim.Comments, Routing.PartNo AS RPartNo, Routing.StepNo, Routing.WorkCntr, Routing.VendCode, ' +
'Routing.Descrip AS StepDescrip, Routing.SetupTime, Routing.CycleTime, ' +
'Routing.WorkOrVend, ' +
'Materials.PartNo as MatPartNo, Materials.SubPartNo, Materials.Qty, ' +
'Materials.Unit, Materials.TotalQty, Materials.ItemNo, Materials.Vendor ' +
'FROM (( Estim ' +
'INNER JOIN Routing ON Estim.PartNo = Routing.PartNo ) ' +
'INNER JOIN Materials ON Estim.PartNo = Materials.PartNo )')
if 'PartNo' in kwargs:
key = kwargs['PartNo']
sql = sql + 'WHERE Estim.PartNo=?'
cursor = con.cursor().execute(sql, key)
# use this for debuging only
num = 0
for row in cursor.fetchall():
num += 1
return num
This works fine for all PartNo except when PartNo contains a decimal point. Curiously, when PartNo contains a decimal point AND a hyphen, I get the appropriate record(s).
kwargs['PartNo'] = "100.100-2" # returns 1 record
kwargs['PartNo'] = "200.100" # returns 0 records
Both PartNos exist when viewed in the other application, so I know there should be records returned for both queries.
My first thought was to ensure kwargs['PartNo'] is a string key = str(kwargs['PartNo']) with no change.
I also tried to places quotes around the 'PartNo' value with no success. key = '\'' + kwargs['PartNo'] + '\''
Finally, I tried to escape the . with no success (I realize this would break most queries, but I'm just trying to track down the issue with a single period) key = str(kwargs['partNo']).replace('.', '"."')
I know using query parameters should handle all the escaping for me, but at this point, I'm just trying to figure out what's going on. Any thoughts on this?
So the issue isn't with the query parameters - everything works as it should. The problem is with the SQL statement. I incorrectly assumed - and never checked - that there was a record in the Materials table that matched PartNo.
INNER JOIN Materials ON Estim.PartNo = Materials.PartNo
will only return a record if PartNo is found in both tables, which in this particular case it is not.
Changing it to
LEFT OUTER JOIN Materials ON Estim.PartNo = Materials.PartNo
produces the expected results. See this for info on JOINS. https://msdn.microsoft.com/en-us/library/bb243855(v=office.12).aspx
As for print (repr(key)) - flask handles the kwarg type upstream properly
api.add_resource(PartAPI, '/api/v1.0/part/<string:PartNo>'
so when I ran this in the browser, I got the "full length" strings. When run in the cmd line using python -c ....... I was not handling the argument type properly as Gord pointed out, so it was truncating the trailing zeros. I didn't think the flask portion was relevant, so I never added that in the original question.

SQL query concatenation to create file path

I need to create a file path from 3 columns in a SQL query. This will be utilized in a file once everything is completed. I have tried using CONCAT and string methods for the columns but no luck. The query is provided below.
SELECT
dbo.TBIndexData.DocGroup,
dbo.TBIndexData.Index1 AS Title,
dbo.TBIndexData.Index2 AS Meeting_Date,
dbo.TBIndexData.Index3 AS Meeting_Number,
dbo.TBIndexData.Index4 AS Meeting_Type,
dbo.TBIndexData.Index5 AS Doc_Name,
dbo.TBIndexData.Index6 AS Doc_Type,
dbo.TBIndexData.Index7 AS Meeting_Page,
dbo.TBIndexData.Index8 AS Notes,
dbo.TBIndexData.Index9 AS TBUser,
dbo.TBIndexData.Index10 AS Date_Scanned,
CONCAT (dbo.TBPrimary.FileDir + '\' + dbo.TBPrimary.TimsFileID + '.' + dbo.TBPrimary.FileExtension) AS FilePath
FROM
dbo.TBIndexData
JOIN
dbo.TBPrimary ON dbo.TBIndexData.DocGroup = dbo.TBPrimary.DocGroup
In SQL Server 2008 you need something like
SELECT I.DocGroup,
I.Index1 AS Title,
I.Index2 AS Meeting_Date,
I.Index3 AS Meeting_Number,
I.Index4 AS Meeting_Type,
I.Index5 AS Doc_Name,
I.Index6 AS Doc_Type,
I.Index7 AS Meeting_Page,
I.Index8 AS Notes,
I.Index9 AS TBUser,
I.Index10 AS Date_Scanned,
P.FileDir + '\' + CAST(P.TimsFileID AS VARCHAR(10)) +
'.' + P.FileExtension AS FilePath
FROM dbo.TBIndexData I
JOIN dbo.TBPrimary P
ON I.DocGroup = P.DocGroup
You shouldn't use schemaname.tablename in the SELECT list. This is not officially supported grammar. Just use tablename or give an alias.
(Using two part names there can lead to confusing errors if calling properties of columns of CLR datatypes)
Try to use CONCAT with commas
CONCAT (dbo.TBPrimary.FileDir, '\', dbo.TBPrimary.TimsFileID, '.', bo.TBPrimary.FileExtension) AS FilePath