In Oracle SQL Developer, I need to switch the active database connection manually. Is there a command that will connect to a different database programmatically, assuming that the login credentials are already saved? I'm trying to avoid clicking on the drop-down menu at the top right of the window which selects the active connection.
Perhaps I should rather have a single SQL file per database? I could understand that argument. But this to prepare to migrate some tables from one database to another and so it's nice to have all of the context in one file.
On database1, run a query on table1 which is located in schema1.
-- manually switch to database1 (looking for a command to replace this step)
ALTER SESSION SET CURRENT_SCHEMA = schema1
SELECT * FROM table1;
On database2, run a query on table2 which is located in schema2.
-- manually switch to database2
ALTER SESSION SET CURRENT_SCHEMA = schema2
SELECT * FROM table2;
Looks like this is well documented here
Use this command
CONN[ECT] [{<logon>| / |proxy} [AS {SYSOPER | SYSDBA | SYSASM}] [edition=value]]
You need a DDL TRIGGER to perform an event after your presql
CREATE TRIGGER sample
ON TABLE
AFTER
Event
........
THEN
ALTER SESSION SET
CURRENT_SCHEMA = schema2
SELECT * FROM table2;
I don't know of a way in which to change your selected connection in SQL Developer, but there is a programmatic method for temporarily changing the connection under which the script commands are run, as #T.S. pointed out. I want to give a few examples, which might be helpful to people (as they would have been for me).
So let's say your script has part A and part B and you want to execute them one after the other but from different connections. Then you can use this:
CONNECT username1/password1#connect_identifier1;
-- Put commands A here to be executed under this connection.
DISCONNECT; -- username1
CONNECT username2/password2#connect_identifier2;
-- Put commands B here to be executed under this connection.
DISCONNECT; -- username2
The connect_identifier part identifies the database where you want to connect. For instance, if you want to connect to a pluggable database on the local machine, you may use something like this:
CONNECT username/password#localhost/pluggable_database_name;
or if you want to connect to a remote database:
CONNECT username/password#IP:port/database_name;
You can omit the password, but then you will have to input it in a prompt each time you run that section. If you want to consult the CONNECT command in more detail, this reference document may be useful.
In order to execute the commands, you would then select the code that you are interested in (including the relevant CONNECT commands) and use Run Script (F5) or just use Run Script (F5) without selecting anything which will execute the entire script file. SQL Developer will execute your commands, put the output into the Script Output tab and then stop the connection. Note that the output of SELECT commands might be unpleasant to read inside Script Output. This can be mitigated by running the following command first (just once):
SET sqlformat ansiconsole;
There is also Run Statement (Ctrl+Enter), but do note that Run Statement (Ctrl+Enter) does not seem to work well with this workflow. It will execute and display each SELECT statement into a separate Query Result tab, which is easier to read, BUT the SELECT query will always be executed from the context of the active connection in SQL Developer (the one in the top right), not the current code connection of the CONNECT statement. On the other hand, INSERT commands, for instance, DO seem to be executed in the context of the current code connection of the CONNECT statement. This (rather inconsistent) behaviour is probably not what you want, so I recommend using Run Script (F5) as described above.
Related
As the title says - when I perform an "INSERT" statement, I can't see the results unless I re-open PL/SQL Developer.
To make things a bit more clear:
After I perform this statement on the empty table "worker_temp" -
insert into worker_temp
select * from worker_b
I see that 100 records have been inserted:
But when I try to see the results using this query:
select * from worker_temp;
I still see an empty table:
But only after I quit PL/SQL Developer and re-open it, I can see the records that I inserted earlier:
Is there a way to see the changes without closing and re-opening PL/SQL Developer?
What I've tried so far:
I've tried to refresh the table using right click on it:
And I've also tried to refresh the whole tables folder:
I also tried committing -
commit;
But I'm not sure what that even is.
Tool agnostic way:
begin
insert into worker_temp
select * from worker_b;
commit;
end;
Judging by all the screenshots you are likely getting separate database sessions in 'each' tab you are using - which is a good thing. You have to issue the commit on the same session that performed the insert. Another way of understanding this:
begin
insert into worker_temp select * from worker_b;
DBMS_OUTPUT.PUT_LINE('Rows inserted but not committed ' || SQL%ROWCOUNT);
-- 'undo' the insert by rolling back the insert instead of commit.
rollback;
end;
The default setting in PL/SQL Developer is Multi session:
This means that each editor window you have open is logged into the database in a separate session. A session can't see another session's changes until it commits. This is rather like saving a shared Excel spreadsheet on a network drive. Nobody can see your changes until you have finished making them, which you'll appreciate is an important feature in a multi-user database.
In PL/SQL Developer, the Multi session default setting means that you can start a long-running query in one SQL window, and then get on with something else in another without being blocked and having to wait for it. With this setting, you'll need to commit your changes before any other editor window can see them. There are Commit and Rollback icons in the toolbar, or you can type commit; and execute it.
However, I always set mine to Dual session, meaning all windows are part of the same session, even if it means I sometimes have to wait for something. I find this simplifies things considerably, and also I can make changes across multiple windows without needing to commit, which can be helpful when working with global temporary tables or alter session commands.
Read more in this setup guide.
I have a session created in my vb.net codes and running some SQL queries, there are some local temp tables like #T1, #T2 , ...
Execution process has some steps and I need to know which data changes in my local tables in each step.
Currently I use this to view the data in my code:
select * into ##T1 from #T1
I can't use sp_getbindtoken because there is no active transaction. I can not use DBCC because I don't have permission.
I can run sys.dm_exec_sessions view and therefor I have active session_id,
I also have connection Index of active sql connection
is there any way to connect to a active session and access local temp tables?
or is there any way to get those data of #T1, #T2,...?
EDIT1:
according to the comment which commented by #SeanLange
I have some temp tables as I said, and in the steps mentioned before I do some calculations on these temp tables, for tracing these calculations I need to know what happens in these steps, and I want to execute a simple select statement on these temp tables. what I wanted to do was connect to the active session created in my source code from an external project called Tracer, and perform select statements while my source is on the fly and meanwhile trace the data created in these session
You can't do it. Sorry. (at least without sa privileges).
Run your queries from within a stored procedure and add code to log whatever you need to a table, then query the log table as needed.
Execution process has some steps and I need to know which data changes in my local tables in each step.
If you have permission, you can create a trigger to do the logging for you
Context: SQL Server 2005
I have a simple proc, which does a bulk load from an external file.
ALTER proc [dbo].[usp_test]
AS
IF OBJECT_ID('tempdb..#promo') is not null BEGIN
DROP TABLE #promo
END
CREATE TABLE #promo (promo VARCHAR(1000))
BULK INSERT #promo
FROM '\\server\c$\file.txt'
WITH
(
--FIELDTERMINATOR = '',
ROWTERMINATOR = '\n'
)
select * from #promo
I can run it in SSMS. But when I call it from another application (Reporting service 2005), it throws this error:
Cannot bulk load because the file "\server\c$\file.txt" could not be opened. Operating system error code 5 (Access is denied.).
Here is complicated because it may related to the account used by reporting service, or some windows security issue.
But I think I can maybe impersonate the login as the one I used to create the proc because the login can run it in SSMS. So tried to change the proc to 'with execute as self', it compiles ok, but when I tried to run it in SSMS, I got:
Msg 4834, Level 16, State 4, Procedure usp_test, Line 12
You do not have permission to use the bulk load statement.
I am still in the same session, so when I run this, it actually execute as the 'self', which is the login I am using now, so why I got this error? What should I do?
I know it's bit unclear so just list the facts.
========update
I just tried using SSIS to load the file into a table so that the report can use. The package runs ok in BIDS but when runs in sql agent job it got the same access to the file is denied error. Then I set up a proxy and let the package run under that account and the job runs no problem.
So I am thinking is it the account ssrs used can't access the file? What account is used by ssrs? Can ssrs be set up to run under a proxy like sql agent does?
==============update again
Finally got it sorted
I have created a SSIS package, put the package in a job (running under a proxy account to access the file), and in the proc to execute the job. This does work although tricky (need to judge whether the job has finished in the proc). This is too tricky to maintain, so just create as a proof of concept, will not go into production.
http://social.msdn.microsoft.com/Forums/sqlserver/en-US/761b3c62-c636-407d-99b5-5928e42f3cd8/execute-as-problem?forum=transactsql
1) The reason you get the "You do not have permission to use the bulk load statement." is because (naturally) you don't have permissions to use the bulk load statement.
You must either be a sysadmin or a bulkadmin at the server level to run BULK commands.
2) Yes, "Access is denied" usually means whatever credentials you are using to run the sproc in SSRS does not have permissions to that file. So either:
Make the file available to everyone.
Set a known credential with full access to the file to the datasource running the sproc.
3) What the heck, dude.
Why not just use the text file directly as a data source in SSRS?
If that's not possible, why not perform all your ETL in one sproc run outside SSRS, and then just use a simple "select * from table" statement for SSRS?
Please do not run a BULK INSERT every time someone wants the report. If they need up to date reads of the file, use the file as a data source. If they can accept, say, a 10 minute lag in data, create a batch job or ETL process to pick the file up and put it into a database table every 10 minutes and just read from that. Write once, read many.
This sutiation can be easily reproduced on your test environment. Open SSMS and connect to you server. Open New Query tab connected to MYTEST database (I assume that MYTEST is online).
Don't do anything with this tab. Open new tab connected to the same database. Type the following code in your new tab
USE master
GO
ALTER DATABASE MYTEST
SET OFFLINE
Your code will be head blocked by the process you are running from your first tab.(Please see Activity Monitor).
Why is the execution blocked even though there is no task accosiated with process in the first tab?
You'd need to tell SQL to kick every connection out
ALTER DATABASE MYTEST
SET OFFLINE
WITH ROLLBACK IMMEDIATE
This is by design: a connection to a database has shared DB lock, whether executing or not.
WITH <termination>::=
Specifies when to roll back incomplete transactions when the database is transitioned from one state to another. If the termination clause is omitted, the ALTER DATABASE statement waits indefinitely if there is any lock on the database. Only one termination clause can be specified, and it follows the SET clauses.
Just run sp_lock (or whatever the new dmvs are :-) and you'll see them
I have a script in T-SQL that goes like this:
create table TableName (...)
SET IDENTITY INSERT TableName ON
And on second line I get error:
Cannot find the object "TableName" because it does not exist or you do not have permissions.
I execute it from Management Studio 2005. When I put "GO" between these two lines, it's working. But what I would like to acomplish is not to use "GO" because I would like to place this code in my application when it will be finished.
So my question is how to make this work without using "GO" so that I can run it programmatically from my C# application.
Without using GO, programmatically, you would need to make 2 separate database calls.
Run the two scripts one after the other - using two calls from your application.
You should only run the second once the first has successfully run anyway, so you could run the first script and on success run the second script. The table has to have been created before you can use it, which is why you need the GO in management studio.
From the BOL: "SQL Server utilities interpret GO as a signal that they should send the current batch of Transact-SQL statements to SQL Server". Therefore, as Jose Basilio already pointed out, you have to make separate database calls.
If this can help, I was faced with the same problem and I had to write a little (very basic) parser to split every single script in a bunch of mini-script which are sent - one at a time - to the database.
something even better than tpdi's temp table is a variable table. they run lightning fast and are dropped automatically once out of scope.
this is how you make one
declare #TableName table (ColumnName int, ColumnName2 nvarchar(50))
then to insert you just do this
insert into #TableName (ColumnName, ColumnName2)
select 1, 'A'
Consider writing a stored proc that creates a temporary table and does whatever it needs to with that. If you create a real table, your app won't be able to run the script more than once, unless it also drops the table -- in which case, you have exactly the functionality of a temp table.