I am trying to execute this statement in mozilla sqlite add-on
alter table (select tbl_name from sqlite_master where rowid=1) add GUID varchar
But this runs into error :
SQLiteManager: Likely SQL syntax error: alter table (select tbl_name from sqlite_master where rowid=1) add GUID varchar [ near "(": syntax error ]
Exception Name: NS_ERROR_FAILURE
Exception Message: Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [mozIStorageConnection.createStatement]
the statement :select tbl_name from sqlite_master where rowid=1 works fine
You cannot do that: in SQL, table names and column names must be identifiers embedded in the SQL string itself. They cannot come from values that you query, or even in a query parameter.
You need to select the table name, make the alter table statement, and then execute it separately.
Related
I know precious nothing abour Rails, so please excuse my naivete about this question.
I'm trying to modify a piece of code that I got from somewhere to make it execute it for a randomly selected bunch of users. Here it goes:
users = RedshiftRecord.connection.execute(<<~SQL
select distinct user_id
from tablename
order by random()
limit 1000
SQL
).to_a
sql = 'select user_id, count(*) from tablename where user_id in (?) group by user_id'
<Library>.on_replica(:something) do
Something::SomethingElse.
connection.
exec_query(sql, users.join(',')).to_h
end
This gives me the following error:
ActiveRecord::StatementInvalid: PG::SyntaxError: ERROR: syntax error at or near ")"
LINE 1: ...ount(*) from tablename where user_id in (?) group by...
^
Users is an array, I know this coz I executed the following and it resulted in true:
p users.instance_of? Array
Would someone please help me execute this code? I want to execute a simple SQL query that would look like this:
select user_id, count(*) from tablename where user_id in (user1,user2,...,user1000) group by user_id
The problem here is that IN takes a list of parameters. Using a single bind IN (?) and a comma separated string will not magically turn it into a list of arguments. Thats just not how SQL works.
What you want is:
where user_id in (?, ?, ?, ...)
Where the number of binds matches the length of the array you want to pass.
The simple but hacky way to do this would be just interpolate in n number of question marks into the SQL string:
binds = Array.new(users.length, '?').join(',')
sql = <<~SQL
select user_id, count(*)
from tablename
where user_id in (#{binds)})
group by user_id'
SQL
<Library>.on_replica(:something) do
Something::SomethingElse.
connection.
exec_query(sql, users).to_h
end
But you would typically do this in a Rails app by creating a model and using the ActiveRecord query interface or using Arel to programatically create the SQL query.
A stored procedure has a session table, I think it adjusted to verify my statements.
Example:
DECLARE GLOBAL TEMPORARY TABLE SESSION.TEMP
(
EMPNO INT,
SALARY DEC(9,2)
)
INSERT INTO SESSION.TEMPM (EMP, SALARY) SQL STATEMENTS;
select count(*) from session.temp;
I just want to know the result of select count(*) from session.temp;
My mode method:
select count(t.*) from (SQL STATEMENTS) t
Is there another way to do this?
To save the returned value of a query (only if it is a one row result) you have to declare a variable like this:
DECLARE iCountTemp INTEGER;
Then you have to insert the value into said var.
SELECT COUNT(*)
INTO iCountTemp
FROM session.temp;
Hope that helps.
I am constantly receiving DB error NO Column found inspite i have recreated column and verified it too many times.
Below is the table structure:
CREATE TABLE "ContractorTester" ("ContrTestID" VARCHAR NOT NULL ,"Ack" VARCHAR NOT NULL ,"TesterLName" VARCHAR,"TesterFName" VARCHAR,"GaugeName1" VARCHAR,"GaugeMake1" VARCHAR,"TestCrossConLic" VARCHAR,"CCLicExpDate" VARCHAR,"GaugeSerialNum1" VARCHAR,"GaugeCalibrDate1" VARCHAR,"ContrCompanyName1" VARCHAR,"ContrAddr1" VARCHAR,"ContrCity1" VARCHAR,"ContrState1" VARCHAR,"ContrZip1" VARCHAR,"ContrPhone1" VARCHAR,"Lat" DOUBLE,"Log" DOUBLE,"MCreatedDate" VARCHAR,"MUpdatedDate" VARCHAR,"ActLocalCT
" VARCHAR,"ContrTestTranID" VARCHAR PRIMARY KEY )
Below is Insert Query:
INSERT OR REPLACE INTO ContractorTester ('GaugeName1','GaugeMake1','ContrPhone1','ContrTestTranID','TesterFName','ContrAddr1','ContrCity1','ContrZip1','CCLicExpDate','TestCrossConLic','GaugeCalibrDate1','Ack','TesterLName','ContrTestID','ContrState1','ContrCompanyName1','GaugeSerialNum1','ActLocalCT','Log','Lat') VALUES ('TK-99F','MIDWEST','(847) 111-3314','0','Jack','819 Main1','Lake Zurich','60051','2016-04-17T00:00:00.003','XC3673','2015-04-17T00:00:00.003','0','Skirm','5','IL','American Backflow Prevention Inc.','TG0605','1','0','0')
Below is the error:
SQLiteManager: Likely SQL syntax error: INSERT OR REPLACE INTO ContractorTester ('GaugeName1','GaugeMake1','ContrPhone1','ContrTestTranID','TesterFName','ContrAddr1','ContrCity1','ContrZip1','CCLicExpDate','TestCrossConLic','GaugeCalibrDate1','Ack','TesterLName','ContrTestID','ContrState1','ContrCompanyName1','GaugeSerialNum1','ActLocalCT','Log','Lat') VALUES ('TK-99F','MIDWEST','(847) 111-3314','0','Jack','819 Main1','Lake Zurich','60051','2016-04-17T00:00:00.003','XC3673','2015-04-17T00:00:00.003','0','Skirm','5','IL','American Backflow Prevention Inc.','TG0605','1','0','0') [ table ContractorTester has no column named ActLocalCT ]
Exception Name: NS_ERROR_FAILURE
Exception Message: Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [mozIStorageConnection.createStatement]
Please any one review and let me know what is the wrong in above Queries.
Thanks in advance.
Replace
INSERT OR REPLACE INTO ContractorTester
with
INSERT OR REPLACE INTO ContractorTester VALUES
Without the VALUES the list in parens is the list of columns to insert into, not the list of values to insert.
I am trying to create a stored procedure in order to insert some data into some table in Oracle 11g.
For this purpose, I need to read the last amount from the latest insert for that user, and then add it to my new value and save the changes as a new row and if any kind of exception is occurred just rollback. This is what I have come up with so far:
CREATE OR REPLACE PROCEDURE MYTESTDB.INSERT_INTO_TESTBANK
(
ID IN TBLTESTBANK.ID%TYPE,
USERID IN TBLTESTBANK.USERID%TYPE,
TYPE IN TBLTESTBANK.TYPE%TYPE,
AMOUNT IN TBLTESTBANK.AMOUNT%TYPE,
DATETIMESTAMP IN TBLTESTBANK.DATETIMESTAMP%TYPE,
TRANSACTION_ID IN TBLTESTBANK.IDTRANS%TYPE,
TOTAL_MONEY IN TBLTESTBANK.TOTALMONEY%TYPE,
COMPUTED_HASH IN TBLTESTBANK.HASH%TYPE
)
IS
BEGIN
DECLARE
LastAmount TBLTESTBANK.TOTALMONEY%TYPE;
BEGIN
SELECT TBLTESTBANK.TOTALMONEY INTO LASTAMOUNT
FROM
(
SELECT TBLTESTBANK.ID
FROM TBLTESTBANK tblbnk
WHERE tblbnk.USERID = USERID
order by max(tblbnk.DATETIMESTAMP)
)
where ROWNUM<2;
EXCEPTION WHEN NO_DATA_FOUND
THEN LastAmount := 0;
END;
LastAmount := LastAmount+ AMOUNT;
INSERT INTO TBLTESTBANK (ID, USERID, TYPE, LastAmount,
DATETIMESTAMP, IDTRANS, TOTALMONEY, HASH
)
VALUES (ID, USERID, TYPE, AMOUNT, DATETIMESTAMP, TRANSACTION_ID, TOTAL_MONEY, COMPUTED_HASH);
COMMIT;
EXCEPTION WHEN OTHERS
THEN
ROLLBACK;
END;
/
Whenever I try to test it, I get a red wiggly line under the first SELECT , and then he TESTBANK.ID in the inner select statements. For the select command it says, sql statement is ignored, and for the TESTBANK.ID it says invalid identifier!
It also doesn't let me add two variables, and keeps saying LastAmount must be declared.
And these are the errors I get :
Error(19,7): PL/SQL: SQL Statement ignored
Error(22,16): PL/SQL: ORA-00904: "TBLTESTBANK"."ID": invalid identifier
Error(32,3): PLS-00201: identifier 'LASTAMOUNT' must be declared
Error(32,3): PL/SQL: Statement ignored
Error(34,3): PL/SQL: SQL Statement ignored
Error(34,47): PL/SQL: ORA-00904: "LASTAMOUNT": invalid identifier
You have two problems:
In your select statement:
SELECT TBLTESTBANK.ID
FROM TBLTESTBANK tblbnk
WHERE tblbnk.USERID = USERID
order by max(tblbnk.DATETIMESTAMP)
You have given the table TBLTESTBANK the alias tblbnk therefor you must use the alias throughout the statement:
SELECT tblbnk.ID -- use the correct alias here
FROM TBLTESTBANK tblbnk
WHERE tblbnk.USERID = USERID
order by max(tblbnk.DATETIMESTAMP)
Second:
in the INSERT statement you have to list columns not values.
INSERT INTO TBLTESTBANK (ID, USERID, TYPE, LastAmount,
DATETIMESTAMP, IDTRANS, TOTALMONEY, HASH
)
should be:
INSERT INTO TBLTESTBANK (ID, USERID, TYPE, AMOUNT, --- column name instead of variable name
DATETIMESTAMP, IDTRANS, TOTALMONEY, HASH
)
And then of course you need to use LastAmount in the values part, not AMOUNT
In general it's not a good idea to have variables with the same name as columns of tables that you use in the procedure. It's easy to shadow a variable with a column. You should rename the variables to avoid any problems there.
Edit (I didn't notice this at first).
You also have an error in the structure of the code. A stored procedure (or function) does not have a DECLARE section:
Your declaration needs to look like this:
CREATE OR REPLACE PROCEDURE MYTESTDB.INSERT_INTO_TESTBANK
(
....
)
IS
-- no DECLARE
-- variables right after the IS keyword
LastAmount TBLTESTBANK.TOTALMONEY%TYPE;
BEGIN
...
END;
You can try below select query to get latest record.
SELECT TB.TOTALMONEY INTO LASTAMOUNT
FROM
TESTBANK TB
WHERE
TB.USERID=USERID
AND
DATETIMESTAMP= (SELECT MAX (TB2.DATETIMESTAMP) FROM TESTBANK TB2
WHERE TB2.USERID=USERID);
I have a column with the type of Varchar in my Postgres database which I meant to be integers... and now I want to change them, unfortunately this doesn't seem to work using my rails migration.
change_column :table1, :columnB, :integer
Which seems to output this SQL:
ALTER TABLE table1 ALTER COLUMN columnB TYPE integer
So I tried doing this:
execute 'ALTER TABLE table1 ALTER COLUMN columnB TYPE integer USING CAST(columnB AS INTEGER)'
but cast doesn't work in this instance because some of the column are null...
any ideas?
Error:
PGError: ERROR: invalid input syntax for integer: ""
: ALTER TABLE table1 ALTER COLUMN columnB TYPE integer USING CAST(columnB AS INTEGER)
Postgres v8.3
It sounds like the problem is that you have empty strings in your table. You'll need to handle those, probably with a case statement, such as:
execute %{ALTER TABLE "table1" ALTER COLUMN columnB TYPE integer USING CAST(CASE columnB WHEN '' THEN NULL ELSE columnB END AS INTEGER)}
Update: completely rewritten based on updated question.
NULLs shouldnt be a problem here.
Tell us your postgresql version and your error message.
Besides, why are you quoting identifiers ? Be aware that unquoted identifiers are converted to lowercase (default behaviour), so there might be a problem with your "columnB" in your query - it appears quoted first, unquoted in the cast.
Update: Before converting a column to integer, you must be sure that all you values are convertible. In this case, it means that columnB should contains only digits (or null).
You can check this by something like
select columnB from table where not columnB ~ E'^[0-9]+$';
If you want your empty strings to be converted to NULL integers, then run first
UPDATE table set columnB = NULL WHERE columnB = '';