I'm mapping two table in ODI and I have a problem.
i've mapped the source table to the target table (called DM_BUSINESS with the columns BUSINESS_ID, NAME, ADDRESS). After that I've created a procedure with:
UPDATE dm_business SET name = CONCAT(name, CONCAT(' ', address)) WHERE name IN (SELECT name FROM dm_business GROUP BY name HAVING COUNT (business_id)>1);
When I run this query myself, with SQLDeveloper, I have no problem and it all works fine: it adds the address of the business to its name, when there are more than one business with the same name.
When I run the procedure with this task, it gives me error ORA-00933: SQL command not properly ended. I have choosen "Oracle" as target technology. What do I do wrong?
Can you help me? Thank you very much.
You should remove the semicolon to run it as an SQL statement or wrap your UPDATE with BEGIN..END to run it as a PL/SQL block:
BEGIN
UPDATE ... ;
END;
Related
I am trying to retrieve employeeIDs using the following sql script:
SELECT * from tblEmployees
GO
CREATE PROCEDURE spGetEmployeeID10
AS
BEGIN
SELECT employeeID
FROM tblEmployees
END
The script runs but returns the entire table with all of the columns' names: employeeID, lastName, firstName, Comment. However, it should only return the employeeID column, no? Am I making an obvious mistake? I am using SQL server management studio 2014. Also, whenever I modify a script and try to re-run it again, I get an error saying that the script already exits. Is there a way to simply edit the script and re-run it with the same name?
Thank you!
"Am I making an obvious mistake?" yes, I'm afraid so, the first select statement is returning everything, an the second is creating a stored procedure. My best guess is that you want this:
CREATE PROCEDURE spGetEmployeeID10
AS
BEGIN
SELECT employeeID
FROM tblEmployees
--my guesswork come further and I added next line
where employeeID = 10
END
GO
EXEC spGetEmployeeID10
GO
What you have is two different operations going on.
The first is your select * which will return everything. The second is the stored procedure creation, which will not return anything. That is why you are seeing the select * results and not the results that are in the stored procedure query.
I have a select statement that needs to look up a customer ID from a customer name. If an ID does not exist for that name, a new record needs to be created in the customer table. this has to be done as part of a select statement (related to the app its being run from).
I tried looking at a UDF that returned either the existing ID or a new ID, before realizing that you can't modify tables from a function.
any idea how to accomplish this?
EDIT:
I think i need to clarify things a bit more. The select statement can and will change on a per-implementation basis. What I'm looking for is a generic way of looking up or creating the customer id (that table and the need to do the lookup does not change) as part of a larger select statement.
the app that is using the sql loads the select statement from a config file, and has 'SELECT' hard coded, so there's no chance of adding an exec before the select etc.
It looks like what I need is something like 'select a.1 (exec dotheLookup(name)) as customerID, a.2 FROM table, but I'm not sure how to go about that.
I suggest you to Create a stored procedure for this. Something like
Create procedure customer
--parameters
AS
Begin
IF exists(Select lookup(customerName) as customerID from table)
BEGIN
--Your select goes here
END
ELSE
BEGIN
--Insert into customer table and return scopeidentity
--Select goes here
END
END
Updated Answer:
You cannot perform data manipulation using select statement.
You could execute a stored procedure before you execute the SELECT statement, the run a function that returns ID from name:
exec CheckForCustomerByNameAndAddIDIfItDoesntExist(customerName)
declare iCustomerID int
select iCustomerID = GetCustomerIDFromName(customerName)
select a.1, a.2, iCustomerID as customerID from table
Something like that
Can you modify the database server? If so, add a linked server pointing to the local server.
EXEC master.dbo.sp_addlinkedserver #server = N'LinkedLocal', #srvproduct=N'', #provider=N'SQLNCLI', #datasrc=N'LocalServerName'
EXEC master.dbo.sp_addlinkedsrvlogin #rmtsrvname=N'LinkedLocal',#useself=N'True',#locallogin=NULL,#rmtuser=NULL,#rmtpassword=NULL
Then just run an OPENQUERY that invokes a stored procedure that does your work:
select * from OPENQUERY("LinkedLocal", 'exec Database.Schema.StoredProcedure ''Param1'', ''Param2'')
I am getting the following error when I execute my stored procedure:
Msg 102, Level 15, State 1, Line 6Incorrect syntax near '2011'.(1 row(s) affected)
Here is the stored procedure:
ALTER PROCEDURE [dbo].[DeliveryFileNames]
AS
BEGIN
SET NOCOUNT ON;
declare #SQL nvarchar(4000)
Create Table #DelivTemp(
Style nvarchar(50),
Material nvarchar(50),
Filename nvarchar(100),
delivered_date date)
set #SQL=
N'insert into #DelivTemp
Select distinct Style,Material,filename
from OPENQUERY(GCS_PRODUCTION,
''SELECT LEFT(FILENAME,locate(''''_'''',FILENAME)-1)as Style,
substring_index(filename,''''_'''',2)as Material,filename,
delivered_date FROM view_delivery_log
where delivered_date > ''2011%'' order by Style '')'
exec (#SQL)
drop table dbo.DelivFN
Select * into dbo.DelivFN
from #DelivTemp
END
I am using OpenQuery to update a SQL table from a linked server on SQL Server 2008 R2.
I know that the underscore is a real issue, but I have tried a plethora of options including \, % and both single and double quotes.
Regardless I am getting the same result. I can run the query independently of the stored procedure and achieve the correct results. The filename field referenced several times is formatted 00000000_ABC4_A.png. I am using the underscore to identify the components of the file name that I need for my reporting purposes.
In addition to the the logical error of your date comparison using the % that the others have pointed out, your current issue is a syntactical error.
Since you've got a dynamic sql statement contained within another dynamic sql statement... you'll need to double-escape all of your single quotes... which you did in most of the query, except for the following line:
where delivered_date > ''2011%'' order by Style '')'
Properly escaped, would be:
where delivered_date > ''''2011%'''' order by Style '')'
Which raises the question... why are you building up the string to execute dynamically, instead of just calling the statement directly?
It's the syntax of ''2011%''. This is not a valid date. % being a wildcard means the compiler can't know what to compare against in the WHERE clause. You'd need to use an actual date: i.e. ''2011_01_01'' so the compiler can know what to compare against
I believe the stored proc exec runs under a different session, therefore you won't have access to the temp table anyway. So, it won't matter if you get that sql statement to run. You could always use YEAR(delivered_date) > 2011.
Another approach would be to use the fqn for the linked server to select into and bypass the temp table all together:
SELECT LEFT(FILENAME,locate('_',FILENAME)-1)as Style,
substring_index(filename,'_',2)as Material,filename,delivered_date
FROM [linked_server_name].[db_name].[dbo].view_delivery_log
into dbo.DelivFN
Let's say sStorecode is: 00020
The following just executes the select statement to get the accountid at another database STORE in the table STOREINFO, for example connecting to p008081 (where 008 is the substring of the sStorecode and 081 is what I am joining below),
but I am getting errors for some reason (Invalid SQL Statement), can someone help?
EXECUTE IMMEDIATE 'select AccountID from STOREINFO#STORE.p'||substr(sSTORECODE,3,3)||'081';
Thanks in advance!
EXECUTE IMMEDIATE is a PL/SQL command. In PL/SQL, the result of a SELECT statement needs to go somewhere. But it your statement, you don't specify where it should go.
So if you expect a single row, you could write:
EXECUTE IMMEDIATE 'select AccountID from STOREINFO#STORE.p'||substr(sSTORECODE,3,3)||'081'
INTO l_account_id;
l_account_id is a local PL/SQL variable.
If you expect several row, you could use
EXECUTE IMMEDATE ... BULK COLLECT INTO l_account_tab;
l_account_tab is a PL/SQL collection variable.
Or if you want to work with cursors, you can write:
OPEN account_id_cv FOR 'select AccountID from STOREINFO#STORE.p'||substr(sSTORECODE,3,3)||'081';
account_id_cv is a REF CURSOR variable.
Seems like that should be something like this instead:
'select AccountID from STORE.STOREINFO WHERE sStorecode = ''p'||substr(sSTORECODE,3,3)||'081''';
I want to execute the following statement through from a linked server (openquery):
UPDATE SAP_PLANT
SET (OWNER, OWNER_COUNTRY) = (SELECT import.AFNAME, import.COUNTRY
FROM SAP_IMPORT_CUSTOMERS import, SAP_PLANT plant
WHERE plant.SAP_FL = import.SAP_NO
AND import.role ='OWNER')
I've tried to form it into the following syntax, without success :(
update openquery(‘my_linked_server, ‘select column_1, column_2 from table_schema.table_name where pk = pk_value’)
set column_1 = ‘my_value1′, column_2 = ‘my_value2′
I hope for you this is no problem?
I guess this is not really a query you want to open, rather an SQL statement you want to execute. So instead of openquery, you shoud use execute. See example G here: http://msdn.microsoft.com/en-us/library/ms188332.aspx
So your script shoul look like
execute ('your sql command here') at my_linked_server
Are you getting syntax error? Your server parameter in the update openquery is missing a trailing quote. Change ```my_linked_servertomy_linked_server'`.