AWS error: Invalid operation: table name "?" specified more than once; - amazon-web-services

the below code works very well in SQL Server 2012, But when I use it in AWS amazon web service will give me a error "Amazon Invalid operation: table name "#t" specified more than once;"
CREATE TABLE #t (store_id varchar(20),city varchar(20),[state] varchar(20));
INSERT INTO #t VALUES
('22', 'new', 'NY'),
('22', null, null),
('22', null, null),
('33', null, null),
('33', 'LA', 'CA')
;
SELECT DISTINCT store_id, city, [state]
INTO #unique
FROM #t WHERE city IS NOT NULL;
;
UPDATE #t
SET city = #unique.city, [state] = #unique.[state]
FROM #unique
INNER JOIN #t
ON #unique.store_id = #t.store_id
WHERE #t.city IS NULL
Does anyone know why and modify my code? Thank you.

Here you go
UPDATE #t
SET city = #unique.city, [state] = #unique.[state]
FROM #unique
WHERE #unique.store_id = #t.store_id
AND #t.city IS NULL
Redshift does not need target table in FROM clause but in case if you need to specify it you need to alias it.
UPDATE #t
SET city = #unique.city, [state] = #unique.[state]
FROM #unique
JOIN #t t1
ON #unique.store_id = t1.store_id
WHERE t1.city IS NULL
From documentation
If you need to include the target table of the UPDATE statement in the list, use an alias.
https://docs.aws.amazon.com/redshift/latest/dg/r_UPDATE.html

Related

Oracle APEX (v19.1.0.00.15) does not fetch raw datatype

I have a table with an id field type of guid/raw(32) as FK.
I created an "Drill Down" page with page wizzard. The wizzard does not put this id field to the edit page. I put it manually but the generated fetch process does not fetch value into it. The page saving works well, include this field. I also test the page with another manually inserted but different field type, it's also works. For testing also created an "Report with Form", and it also works well. It use another method, not fetch process. Is there any trick to make it work?
I was able to reproduce this behavior, but it seemed consistent with other regions, such as a Report with Form. I suppose this could be argued in different ways because RAW values can't really be displayed except as a bunch of ones and zeros which isn't really useful. You'd have to convert the value to something like HEX and APEX shouldn't have much of a say in how that's done.
A workaround that I had success with was to create a view on top of the table which does an explicit conversion of the RAW type to HEX using RAWTOHEX. Here's an example script:
create table p (
id raw(16) default sys_guid() primary key,
name varchar2(10) not null
);
create table c (
id raw(16) default sys_guid(),
parent_id raw(16) not null
constraint c_p_id_fk
references p,
name varchar2(10) not null
);
declare
l_p1_id raw(16);
l_p2_id raw(16);
l_p3_id raw(16);
begin
insert into p (name) values ('p 1') returning id into l_p1_id;
insert into p (name) values ('p 2') returning id into l_p2_id;
insert into p (name) values ('p 3') returning id into l_p3_id;
insert into c (parent_id, name) values (l_p1_id, 'c 1 p 1');
insert into c (parent_id, name) values (l_p1_id, 'c 2 p 1');
insert into c (parent_id, name) values (l_p2_id, 'c 3 p 2');
insert into c (parent_id, name) values (l_p3_id, 'c 4 p 3');
insert into c (parent_id, name) values (l_p3_id, 'c 5 p 3');
insert into c (parent_id, name) values (l_p3_id, 'c 6 p 3');
end;
/
create view p_v
as
select rawtohex(id) as id,
name
from p;
I then created the Master Detail page using the ROWID pseudo column instead of the PK column so that the PK field would be editable (though I'm still not sure why one would want to do this).

How to ajax refresh a region in ORACLE Apex - based on a selection in a Badge List [Plugin]

I have a badge list plug in returning a few items:
SQL for the badgel list plug-in is below:
WITH
STUDY_MV AS
(
SELECT /* MATERIALIZE */
* FROM VW_GRET_CTA_STUDIES
WHERE GRET_ID = :P14_GRET_ID
AND STUDY_CODE = :P14_STUDY_CODE
AND VARIATION_REQUEST_ID IS NULL
AND APPLICATION_TYPE = 'Clinical Trial Application'
)
select
'1) Despatched CTA' as label,
(SELECT COUNT(DISTINCT REGISTRATION_UID) FROM STUDY_MV
WHERE
STUDY_STATUS = 'Despatched'
) as value,
'Despatched' AS STUDY_STATUS,
APEX_PAGE.GET_URL (
p_page => 15,
p_items => 'P15_GRET_ID,P15_PREVIOUS_PAGE,P15_STUDY_CODE,P15_STUDY_STATUS',
p_values => :P14_GRET_ID || ',14,' || :P14_STUDY_CODE || ',Despatched') as url
from dual
UNION
select
'2) Submitted CTA' as label,
(SELECT COUNT(DISTINCT REGISTRATION_UID) FROM STUDY_MV
WHERE
STUDY_STATUS = 'Submitted'
) as value,
'Submitted' AS STUDY_STATUS,
APEX_PAGE.GET_URL (
p_page => 15,
p_items => 'P15_GRET_ID,P15_PREVIOUS_PAGE,P15_STUDY_CODE,P15_STUDY_STATUS',
p_values => :P14_GRET_ID || ',14,' || :P14_STUDY_CODE || ',Submitted') as url
from dual
This works...
I was originally using the URL to go to another page (page 15), and was passing parameters to it...but I now need to do a refresh (ajax/dynamic action) of another region on the same page based on the selection in the badge list. i.e. if they click the "Submitted" bage, then an interactive grid on the same page gets refreshed over ajax to only show "Submitted" records).
The interactive grid has the following SQL:
SELECT
DISTINCT
reg_flag_passive,
study_status,
registration_uid,
application_stage,
application_type,
lu_withdrawn_dt,
country_display_label,
authorization_status,
registration_name_details,
registration_number,
reg_remarks,
region,
preferred_trade_name,
lu_despatched_dt,
LU_SUBMITTED_DT,
lu_resubmitted_dt,
lu_approved_dt,
lu_non_submission_approval_dt,
lu_approved_inc_non_sub_year,
lu_approved_inc_non_sub_dt,
lu_cancelled_dt,
lu_report_due_dt,
lu_rejected_dt,
lu_planned_submission_dt,
LU_EXPECTED_APPROVAL_DT,
cta_ind_no,
study_code,
gret_id
FROM
vw_gret_cta_studies WHERE STUDY_CODE = :P14_STUDY_CODE AND GRET_ID = :P14_GRET_ID
AND VARIATION_REQUEST_ID IS NULL
AND APPLICATION_TYPE = 'Clinical Trial Application'
AND
1 = (CASE WHEN :P14_STUDY_STATUS IS NULL THEN 1 ELSE CASE WHEN STUDY_STATUS = :P14_STUDY_STATUS THEN 1 ELSE 0 END END)
What I need to do is POPULATE the :P14_STUDY_STATUS page item, to session, with the selected STUDY_STATUS value clicked within the badge-list plug in, and then perform a refresh of the interactive grid region - which will pick up the :P14_STUDY_STATUS value in the query.
I am guessing that in order to write things into session via javascript, and then refresh a region (e.g. call a dynamic action to do it) - then I need to perhaps modify the URL I am generating in the badge list SQL to make a javascript call? But having no luck at all.

How to add a partition boundary only when not exists in SQL Data Warehouse?

I am using Azure SQL Data Warehouse Gen 1, and I create a partition table like this
CREATE TABLE [dbo].[StatsPerBin1](
[Bin1] [varchar](100) NOT NULL,
[TimeWindow] [datetime] NOT NULL,
[Count] [int] NOT NULL,
[Timestamp] [datetime] NOT NULL)
WITH
(
DISTRIBUTION = HASH ( [Bin1] ),
CLUSTERED INDEX([Bin1]),
PARTITION
(
[TimeWindow] RANGE RIGHT FOR VALUES ()
)
)
How should I split a partition only when there is no such boundary?
First I think if I can get partition boundaries by table name, then I can write a if statement to determine add partition boundary or not.
But I cannot find a way to associate a table with its corresponding partition values, the partition values of all partitions can be retrieved by
SELECT * FROM sys.partition_range_values
But it only contains function_id as identifier which I don't know how to join other tables so that I can get partition boundaries by table name.
Have you tried joining sys.partition_range_values with sys.partition_functions view?
Granted we cannot create partition functions in SQL DW, but the view seems to be still supported.
I know this is an out of date question, but I was having the same problem. Here is a query I ended up with that can get you started. It is modified slightly from a query for SQL Server documentation:
SELECT s.[name] AS [schema_name]
, t.[name] AS [table_name]
, p.[partition_number] AS [partition_number]
, rv.[value] AS [partition_boundary_value]
, p.[data_compression_desc] AS [partition_compression_desc]
FROM sys.schemas s
JOIN sys.tables t ON t.[schema_id] = s.[schema_id]
JOIN sys.partitions p ON p.[object_id] = t.[object_id]
JOIN sys.indexes i ON i.[object_id] = p.[object_id]
AND i.[index_id] = p.[index_id]
JOIN sys.data_spaces ds ON ds.[data_space_id] = i.[data_space_id]
LEFT JOIN sys.partition_schemes ps ON ps.[data_space_id] = ds.[data_space_id]
LEFT JOIN sys.partition_functions pf ON pf.[function_id] = ps.[function_id]
LEFT JOIN sys.partition_range_values rv ON rv.[function_id] = pf.[function_id]
AND rv.[boundary_id] = p.[partition_number]

error with query REPLACE using mysql PDO

I try to execute the following mysql query with pdo
REPLACE INTO session SET id = :id, user_id = :user_id, data = :data, timestamp = :timestamp
and I get the following error:
[18-Sep-2014 11:48:10] Exception Message: Unhandled Exception.
SQLSTATE[42000]: Syntax error or access violation: 1064 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 '?, data = ?, timestamp = ?' at line 1.
You can find the error back in the log.:
Query:REPLACE INTO session SET id = :id, user_id = :user_id, data = :data, timestamp = :timestamp
Params:
Array
(
[id] => sv9o264ciicsfd8porp1v0gl46
[user_id] => 0
[data] => version|s:8:"computer";linkedin|a:1:{s:5:"state";s:7:"Q7HXzKo";}github|a:1:{s:5:"state";s:7:"Q7HXzKo";}
[timestamp] => 1411030090
)
My Table session structure is:
CREATE TABLE IF NOT EXISTS `session` (
`id` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`user_id` mediumint(10) NOT NULL,
`data` text COLLATE utf8_unicode_ci NOT NULL,
`timestamp` int(40) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `session` (`id`),
UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
When I use phpmyadmin to execute it is working fine.
Can you help me to understand what is the problem?
well I found it, very silly mistake: I should separate the , from the parameter:
I changed this
:user_id,
to:
:user_id ,
You have forgotten an equal sign.
Change this part of your query:
user_id :user_id
to:
user_id = :user_id
I also think there may be a problem in using a reserved keyword like timestamp for one of your columns, try changing it to something like tstamp. You could also try to quote the name in the query.
REPLACE INTO session SET `id` = :id, `user_id` = :user_id, `data` = :data, `timestamp` = :timestamp

SqlQuery one named placeholders several times

I tried
QSqlQuery query;
query.prepare("DELETE FROM names WHERE id_col = :ID OR id_parent = :ID");
query.bindValue(":ID", idVal);
query.exec();
assuming that idVal will be binded two times, but executing this query only rows with id_parent = idVal is deleted, with id_col = idVal remains undeleted. So only second time idVal was binded to the query.
When I rewrite it to
QSqlQuery query;
query.prepare("DELETE FROM names WHERE id_col = ? OR id_parent = ?");
query.bindValue(0, idVal);
query.bindValue(1, idVal);
query.exec();
everything worked as expected.
Is it a way to use one named placeholders several time in QSqlQuery?
From the QSqlQuery::bindValue() documentation:
Values cannot be bound to multiple locations in the query, eg:
INSERT INTO testtable (id, name, samename) VALUES (:id, :name, :name)
Binding to name will bind to the first :name, but not the second.
The last sentence appears to be slightly wrong as it looks like it binds to the second :name, but either way, this clearly states what you are trying to achieve is not supported by Qt.
Your options are to stick with the workaround you already have, or use the solution provided by Mahmoud Gamal in the comment to your question.
To see what query was actually executed, you can use QSqlQuery::executedQuery().
And you should explicitly set values for placeholders:
QSqlQuery query;
query.prepare("DELETE FROM names WHERE id_col = :ID_COL OR id_parent = :ID_PAR");
query.bindValue(":ID_COL", idVal);
query.bindValue(":ID_PAR", idVal);
query.exec();
Also it will be useful if you will need refactoring in future.
Try this first do:
select * from names where :ID in
((select id_col FROM names WHERE id_col = :ID)
OR
(select id_parent FROM names WHERE id_parent = :ID)
);
if the above select returned the right data then use the following as your query:
delete from names where :ID in
((select id_col FROM names WHERE id_col = :ID)
OR
(select id_parent FROM names WHERE id_parent = :ID)
);