I have an SSRS Report which is getting data from AS400 Database. The query I used in the datasource is a UNION of two queries.
SELECT 'SOLD' AS STATUS, SLSMCD, SLYEAR, SLMONTH, SUM(SLDLVQT) + SUM(SLADVQT) - SUM(SLDLVQTC) - SUM(SLADVQTC) AS TotalDlvr
FROM VEHICLE.VHTSALSUM
WHERE (SLFRAN = ?) AND (SLBRCD = ?) AND (SLDPCD = ?) AND (SLSMCD = ?) AND (SLYEAR IN (?, ?, ?))
GROUP BY SLSMCD, SLYEAR, SLMONTH
UNION ALL
SELECT 'TARGET' AS STATUS, STGTCODE AS SLSMCD, STGTYEAR AS SLYEAR, STGTMONTH AS SLMONTH, STGTUNIT AS TotalDlvr
FROM VEHICLE.VHTSALETGT
WHERE STGTFRAN = ? AND STGTDPCD = ? AND STGTCODE = ? AND STGTYEAR IN (?) AND STGTTYPE = 'EXEC'
on running the query I get the error
"Number of host variables in not valid"
The number of host variables is not same as the number of parameter markers specified in the sql statement
I copied the query in AS400 and gave the parameters the query is running successfully.
In SSRS I removed the? and put the parameters values and it is working successfully. But if there is even a single? mark I get the above error.
Related
I have a data frame in pyspark like below
df = spark.createDataFrame(
[
('2021-10-01','A',25),
('2021-10-02','B',24),
('2021-10-03','C',20),
('2021-10-04','D',21),
('2021-10-05','E',20),
('2021-10-06','F',22),
('2021-10-07','G',23),
('2021-10-08','H',24)],("RUN_DATE", "NAME", "VALUE"))
Now using this data frame I want to update a table in MySql
# query to run should be similar to this
update_query = "UPDATE DB.TABLE SET DATE = '2021-10-01', VALUE = 25 WHERE NAME = 'A'"
# mysql_conn is a function which I use to connect to `MySql` from `pyspark` and run queries
# Invoking the function
mysql_conn(host, user_name, password, update_query)
Now when I invoke the mysql_conn function by passing parameters the query runs successfully and the record gets updated in the MySql table.
Now I want to run the update statement for all the records in the data frame.
For each NAME it has to pick the RUN_DATE and VALUE and replace in update_query and trigger the mysql_conn.
I think we need to a for loop but not sure how to proceed.
Instead of iterating through the dataframe with a for loop, it would be better to distribute the workload across each partitions using foreachPartition. Moreover, since you are writing a custom query instead of executing one query for each query, it would be more efficient to execute a batch operation to reduce the round trips, latency and concurrent connections. Eg
def update_db(rows):
temp_table_query=""
for row in rows:
if len(temp_table_query) > 0:
temp_table_query = temp_table_query + " UNION ALL "
temp_table_query = temp_table_query + " SELECT '%s' as RUNDATE, '%s' as NAME, %d as VALUE " % (row.RUN_DATE,row.NAME,row.VALUE)
update_query="""
UPDATE DBTABLE
INNER JOIN (
%s
) new_records ON DBTABLE.NAME = new_records.NAME
SET
DBTABLE.DATE = new_records.RUNDATE,
DBTABLE.VALUE = new_records.VALUE
""" % (temp_table_query)
mysql_conn(host, user_name, password, update_query)
df.foreachPartition(update_db)
View Demo on how the UPDATE query works
Let me know if this works for you.
The following code is a function to retrieve the input and store the record to a table in mysql
def addrecord():
cstmid = tcstmid.get("1.0") # retrieve input
cstmpass = tcstmpass.get("1.0")
cstname = tcstname.get("1.0")
cstmdob = tcstmdob.get("1.0")
cstmsex = v.get()
cstmaddress = tcstmaddress.get("1.0")
#DATABASE CONNECTION
conn=sqltor.connect(host="localhost",user="root",passwd="iwakiri",database="APPARELSTORE")
tkcursor=conn.cursor(prepared=True)
query=("Insert into customer(cstmid,cstmpass,cstmname,cstmdob,cstmsex,cstmaddress) values ('%s','%s','%s','%s','%s','%s')")
tkcursor.execute(query)
conn.commit()
tkcursor.close()
The following code is for making radio buttons with options to select gender
import tkinter as tk
root = tk.Tk()
root.geometry("325x400")
root.title("Apparel store")
# Gender Label
lcstmsex = tk.Label(root, font=('helvetica', 10), text='Select Gender:')
lcstmsex.grid(row=9, column=1)
# Radio Button
v = tk.IntVar()
v.set(0)
# Radio Button for Gender
r1 = tk.Radiobutton(root, text='Female', value=1, variable=v)
r1.grid(row=10, column=1)
r2 = tk.Radiobutton(root, text='Male', value=2, variable=v)
r2.grid(row=11, column=1)
r3 = tk.Radiobutton(root, text='Other', value=3, variable=v)
r3.grid(row=12, column=1)
ERROR:
mysql.connector.errors.ProgrammingError: 1054 (42S22): Unknown column 'cstmsex' in 'field list'
QUESTION:
What am I doing wrong with the code for the radio button and how can I fix it so that I can enter records into tkinter gui and store them in a table in MySQL?
This:
Insert into customer(cstmid,cstmpass,cstmname,cstmdob,cstmsex,cstmaddress) values ...
is not a valid INSERT statement.
Right after the table's name, inside the parentheses you must enumerate all the columns that will receive the values that you supply.
What you are doing though, is passing the variables where you saved the values of the columns.
So change the statement to this:
query = "Insert into customer(id, pass, name, dob, sex, address) values (?, ?, ?, ?, ?, ?)"
tkcursor.execute(query, (cstmid, cstmpass, cstmname, cstmdob, cstmsex, cstmaddress,))
I use ? placeholders for the column values which are passed in the method execute() as a tuple.
Change the names of the columns to the actual ones.
My question has 2 parts, and i am unsure if it is my query which is causing the error or data adapter.
Part 1. I have a mySQL query which works fine on SQLyog, the query involves selection from tables existing in different databases. And both databases has been set to have the same accecss rights for the user account used at the connection string.
Below will be my query.
SELECT `portaldb`.`users`.`full_name` AS 'Name of User'
,`Systemrevamp`.`System_countries`.`CountryName` AS 'Quoted For'
,`Systemrevamp`.`uniquequote`.`UniqueQuote` AS 'System Quote ID'
, IF (
LEFT(`Systemrevamp`.`uniquequote`.`username`, 1) = ' '
,'Web Access'
,'Bulk Upload'
) AS 'Type'
,DATE_FORMAT(`Systemrevamp`.`uniquequote`.`insertedon`, '%d-%b-%Y') AS 'Quoted On'
FROM `portaldb`.`users`
INNER JOIN `Systemrevamp`.`uniquequote` ON TRIM(`Systemrevamp`.`uniquequote`.`UserName`) = `portaldb`.`users`.`usrname`
INNER JOIN `Systemrevamp`.`System_countries` ON `Systemrevamp`.`System_countries`.`Code` = `Systemrevamp`.`uniquequote`.`CountryCode`
INNER JOIN `portaldb`.`permission_details` ON `portaldb`.`permission_details`.`user_ID` = `portaldb`.`users`.`user_ID`
WHERE `portaldb`.`permission_details`.`group_ID` = '5'
AND `Systemrevamp`.`uniquequote`.`insertedon` >= (NOW() - INTERVAL 3 MONTH)
ORDER BY `portaldb`.`users`.`full_name` ASC,`Systemrevamp`.`uniquequote`.`insertedon` ASC
Visual studio keeps telling me there is syntax error and to check the version of SQL, but I am able to retrieve at the database.
Part 2. Below is a snippet of my code. My question for this part is, if the above query is used, what source table should I put for the data adapter to fill at 'XXX'?
myDataAdapter = New MySqlDataAdapter(strSQL, myConnection)
allUserDataset = New DataSet()
myDataAdapter.Fill(allUserDataset, "XXX")
gvAllQuotes.DataSource = allUserDataset
gvAllQuotes.DataBind()
Please let me know if more information is needed. Thank you.
SQL Code:
SELECT id, album_date AS timestamp, CONCAT((SELECT detail_value
FROM people_db.user_details_tbl WHERE detail_field = 'first_name' AND user_id = pictures_db.albums.owner), ' uploaded pictures!') AS title_html
FROM pictures_db.albums
WHERE id IN
(SELECT DISTINCT(album_id)
FROM pictures_db.album_pics
WHERE pic_id IN
(SELECT DISTINCT(picture_id)
FROM pictures_db.picture_access_tbl
WHERE grantee_group_id IN
(SELECT group_id
FROM people_db.group_membership_tbl
WHERE member_id = '2'
)
)
);
PHP Code:
$albums_sql = mysql_query("SELECT id, album_date AS timestamp, CONCAT((SELECT detail_value
FROM people_db.user_details_tbl
WHERE detail_field = 'first_name' AND user_id = pictures_db.albums.owner), ' uploaded pictures!') AS title_html
FROM pictures_db.albums
WHERE id IN (
SELECT DISTINCT(album_id)
FROM pictures_db.album_pics
WHERE pic_id IN (
SELECT DISTINCT(picture_id)
FROM pictures_db.picture_access_tbl
WHERE grantee_group_id IN (
SELECT group_id
FROM people_db.group_membership_tbl
WHERE member_id = '2'
)
)
)") or die(mysql_error());
When the PHP is run, the error is: Table 'pictures_db.albums' doesn't exist
I tried executing as the same user, regranted all permissions, and even flushed privileges. Works in shell, not in PHP.
Any ideas?
The error message is quite clear: MySQL sees the database pictures_db but not the table albums.
That could be due to permissions, but you seem to have checked that thoroughly.
Another possible reason is that the connection string you're using in PHP points to a different database instance than the one you're using at the command line. Perhaps the connection string still points to a different environment, such as DEV but you're in QA or points to an old test version of the database?
Do you call mysql_select_db() before running the query?
mysql_select_db('pictures_db');
I would like to only insert or update a row, if the following SELECT returns a 0 or no rows.
SELECT (value = ? AND status = ? AND connected = ?)
FROM channels, data
WHERE data.channel_id = channels.channel_id AND channels.channel_name = ? AND sample_time < ?
ORDER BY sample_time DESC
LIMIT 1
Basically, it is a data archiver that only writes changes. That is it only writes data for a given sample_time, if the data is not the same as what was written for the previous sample_time. This SELECT gets the data for a given channel for the previous sample_time and compares it to the data that has come along for the current sample_time. So if this returns 0, that is the data is different, it should go ahead and write it. And if no data has been written for this channel yet, then it should return no rows, and the new data should be written. The following is my query for writing the data:
INSERT INTO data (acquire_time, sample_time, channel_id, value, status, connected)
SELECT ?, ?, channels.channel_id, ?, ?, ?
FROM channels
WHERE channel_name = ?
ON DUPLICATE KEY UPDATE acquire_time = ?, value = ?, status = ?, connected = ?
New data for the current sample_time may overwrite previous data for the current sample_time using the ON DUPLICATE KEY UPDATE, just not if it is the same as the data stored for the previous sample_time.
The duplicate key is the combination of the channel_id and sample_time. There is also a unique index on the channel_id and acquire_time.
Thank you for your time.
After your clarifications below, I believe this will do what you want:
INSERT INTO data (acquire_time, sample_time, channel_id, value, status, connected)
SELECT ?, ?, channels.channel_id, ?, ?, ?
FROM channels
WHERE channel_name = ?
AND NOT EXISTS (
SELECT 1
FROM (
SELECT value, status, connected
FROM channels, data
WHERE data.channel_id = channels.channel_id AND channels.channel_name = ?
AND sample_time < ?
ORDER BY sample_time DESC
LIMIT 1
) a
WHERE a.value = ? and a.status = ? and a.connected = ?
)
ON DUPLICATE KEY UPDATE acquire_time = ?, value = ?, status = ?, connected = ?;