nhibernate two different databases in the same session - nhibernate

When writing sql, I can do
BEGIN Trans t;
SELECT a.name, b.name from db1.dbo.A as a
JOIN db2.dbo.B as b
ON b.aId = a.Id
COMMIT Trans t;
When two databases are on the same database instance.
I am wondering how I can achieve this with database mapping. So that I don't need to create multiple sessions for queries involves different databases.

No, so far I have not seen any other solution then creating a view within one database which does the cross DB query and then use nh mappings on that view, or maybe fully-qualified names. (see duplicate-link below your post).

There is a possibility to do it with DB synonyms. It is not an optimal solution performance-wise, but it might solve your current bind.
SQL Server Synonyms

Related

Oracle 11g SQL: Can you use a dblink called up from a dblink

Say you have a database A which has a stored dblink to database B, and database B has a stored dblink to database C.
Is there a way to run a query from A on data which is on C?
I've tried
Select * from ALL_DB_LINKS#B#C
Which does not work (for me at least)
In B, you can create a synonym for object_name#C. In A, you can then query synonym_name#B.
Obviously, that's not going to be the most efficient approach in the world-- moving data across the network twice, enlisting three databases in a two-phase commit, and ensuring that any predicates (or joins) are applied in the correct database would be a highly non-trivial endeavor.

Join two tables from separate database

How can i open db connection from stored procedure. is it possible ? is there any command to do this ?
I want use two db in one query but ef return error for using two dbcontext. How can i join two different db's table anyway?
from a in dbContextArch.Archive
left join dbContextMain.Envelope
on
The best way of doing it is by using a Synonym, which will be mapped to the table on the other server. It can be created as below;
CREATE SYNONYM [dbo].[SYN_dbContextMain] FOR [dbContextMain].[dbo].[Envelope]
Then in your queries, all you need to do, is to use the synonym created instead of the server name;
from a in dbContextArch.Archive
left join SYN_dbContextMain
on ..

creating a table only if it's not existing with ANSI sql

I am trying to dynamically create a SQL table only if it's not already existing. I have seen many solutions on the internet but they usually rely on a specific database, while I'm trying to find the most generic solution.
I was thinking of always running the CREATE command and then assuming that if it fails then the table exist and I can start inserting data into it. I can't see any flaw in this reasoning (not counting performance issues), but I might be wrong.
Is this an acceptable method?
Can you suggest other methods which are database independent, or that use ANSI SQL that all RDBMS would accept?
if there is a table - say - EMP, does that really imply that it is the same EMP that you are expecting?
Either query the appropriate data dictionary for the table structure, or fill your code with a ton of error checking and conditional logic...
INFORMATION_SCHEMA is part of the ANSI SQL Standard, so you should be able to:
IF NOT EXISTS(SELECT NULL FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'YourTable')
CREATE TABLE...
what about: create table if not exists

SQL Server NOLOCK and joins

Background: I have a performance-critical query I'd like to run and I don't care about dirty reads.
My question is; If I'm using joins, do I have to specify the NOLOCK hint on those as well?
For instance; is:
SELECT * FROM table1 a WITH (NOLOCK)
INNER JOIN table2 b WITH (NOLOCK) ON a.ID = b.ID
Equivalent to:
SELECT * FROM table1 a WITH (NOLOCK)
INNER JOIN table2 b ON a.ID = b.ID
Or will I need to specify the (NOLOCK) hint on the join to ensure I'm not locking the joined table?
I won't address the READ UNCOMMITTED argument, just your original question.
Yes, you need WITH(NOLOCK) on each table of the join. No, your queries are not the same.
Try this exercise. Begin a transaction and insert a row into table1 and table2. Don't commit or rollback the transaction yet. At this point your first query will return successfully and include the uncommitted rows; your second query won't return because table2 doesn't have the WITH(NOLOCK) hint on it.
I was pretty sure that you need to specify the NOLOCK for each JOIN in the query. But my experience was limited to SQL Server 2005.
When I looked up MSDN just to confirm, I couldn't find anything definite. The below statements do seem to make me think, that for 2008, your two statements above are equivalent though for 2005 it is not the case:
[SQL Server 2008 R2]
All lock hints are propagated to all the tables and views that are accessed by the query plan, including tables and views referenced in a view. Also, SQL Server performs the corresponding lock consistency checks.
[SQL Server 2005]
In SQL Server 2005, all lock hints are propagated to all the tables and views that are referenced in a view. Also, SQL Server performs the corresponding lock consistency checks.
Additionally, point to note - and this applies to both 2005 and 2008:
The table hints are ignored if the table is not accessed by the query plan. This may be caused by the optimizer choosing not to access the table at all, or because an indexed view is accessed instead. In the latter case, accessing an indexed view can be prevented by using the OPTION (EXPAND VIEWS) query hint.
Neither. You set the isolation level to READ UNCOMMITTED which is always better than giving individual lock hints. Or, better still, if you care about details like consistency, use snapshot isolation.

Create a temp table in PL/SQL

I'm working with an Oracle 10g database, and I want to extract a group of records from one table, and then use that for pulling records out of a bunch of related tables.
If this were T-SQL, I'd do it something like this:
CREATE TABLE #PatientIDs (
pId int
)
INSERT INTO #PatientIDs
select distinct pId from appointments
SELECT * from Person WHERE Person.pId IN (select pId from #PatientIDs)
SELECT * from Allergies WHERE Allergies.pId IN (select pId from #PatientIDs)
DROP TABLE #PatientIDs
However, all the helpful pages I look at make this look like a lot more work than it could possibly be, so I think I must be missing something obvious.
(BTW, instead of running this as one script, I'll probably open a session in Oracle SQL Developer, create the temp table, and then run each query off it, exporting them to CSV as I go along. Will that work?)
Oracle has temporary tables, but they require explicit creation:
create global temporary table...
The data in a temporary table is private for the session that created it and can be session-specific or transaction-specific. If data is not to be deleted until the session ends, you need to use ON COMMIT PRESERVE ROWS at the end of the create statement. There's also no rollback or commit support for them...
I see no need for temp tables in the example you gave - it risks that updates made to the APPOINTMENTS table since the temp table was populating won't be reflected. Use IN/EXISTS/JOIN:
SELECT p.*
FROM PERSON p
WHERE EXISTS (SELECT NULL
FROM APPOINTMENTS a
WHERE a.personid = a.id)
SELECT p.*
FROM PERSON p
WHERE p.personid IN (SELECT a.id
FROM APPOINTMENTS a)
SELECT DISTINCT p.*
FROM PERSON p
JOIN APPOINTMENTS a ON a.id = p.personid
JOINing risks duplicates if there are more than one APPOINTMENT records associated to a single PERSON record, which is why I added the DISTINCT.
Oracle doesn't have the facility to casually create temporary tables in the same way as SQL Server. You have to create the table explicitly in the database schema (create global tempory table). This also means that you need permissions that allow you to create tables, and the script must explicitly be deployed as a database change. The table is also visible in a global name space.
This is a significant idiomatic difference between Oracle and SQL Server programming. Idiomatic T-SQL can make extensive use of tempory tables and genuine requirements to write procedural T-SQL code are quite rare, substantially because of this facility.
Idiomatic PL/SQL is much quicker to drop out to procedural code, and you would probably be better off doing this than trying to fake temporary tables. Note that PL/SQL has performance oriented constructs such as flow control for explicit parallel processing over cursors and nested result sets (cursor expressions); recent versions have a JIT compiler.
You have access to a range of tools to make procedural PL/SQL code run quickly, and this is arguably idiomatic PL/SQL programming. The underlying paradigm is somewhat different from T-SQL, and the approach to temporary tables is one of the major points where the system architecture and programming idioms differ.
While the exact problem has been solved, if you want to build up some useful skills in this area, I would take a look at PL/SQL Collections, and particularly bulk SQL operations using pl/sql collections (BULK COLLECT / Bulk Binds), the RETURNING clause, and defining collections using %ROWTYPE.
You can dramatically reduce the amount of pl/sql code you write through understanding all the above - although always remember that an all-SQL solution will almost always beat a PL/SQL one.