advantages of synonyms IN SQL? - rdbms

why synonyms are used?,advantages of syNONYMS IN SQL?

They're just shorthand names for objects inside a database. For example, you can create a synonym called Products if you have a namespace'd table in a database called ProductionControl.Inventory.Products. They're also handy for controlling named access to other databases in stored procedures. If you have SPs that refer to tables in other databases, creating a synonym and using that instead gives you more control in case the target of the synonym ever changes. This is useful in scenarios where you have SPs that refer to a development database, but when you deploy to production the name is different. So you'd just update the synonym and you'd be OK.

From MSDN Understanding Synonyms
A synonym is a database object that
serves the following purposes:
Provides an alternative name for another database object, referred to
as the base object, that can exist on
a local or remote server.
Provides a layer of abstraction that protects a client application
from changes made to the name or
location of the base object.

In some enterprise systems, you may have to deal with remote objects over which you have no control. For example, a database that is maintained by another department or team.
Synonyms can help you decouple the name and location of the underlying object from your SQL code. That way you can code against a synonym table even if the table you want is moved to a new server/database or renamed.
For example, I could write a query like this:
insert into MyTable
(...)
select ...
from remoteServer.remoteDatabase.dbo.Employee
but then if the server, or database, schema, or table changes it would impact my code. Instead I can create a synonym for the remote server and use the synonym instead:
insert into MyTable
(...)
select ...
from EmployeeSynonym
If the underlying object changes location or name, I only need to update my synonym to point to the new object.
http://www.mssqltips.com/sqlservertip/1820/use-synonyms-to-abstract-the-location-of-sql-server-database-objects/

Related

See Create database queries by modelBuilder

currently I am working at a project which requires to be backwards compatible with (non-EF) databases, but also want to create a new database from model.
For this task I save the current schema somewhere (in XML form) and update the databases with raw sql update steps, until they match the schema, which is working fine.
Also, the modelBuilder matches the schema (as in, my algorithm finds no difference between the newly created database by context.Database.Create() and my saved schema) currently.
Since the schema will most likely change in later stages of development, I do have to support two ways to create an Up-to-date database and was wondering if I could combine these two - since now I have to update the saved target schema, create the update steps AND update my modelBuilder so that is creates exactly the database I need - which would be quite a tedious task.
So since there is probably no way to "translate" my schema to modelBuilder entries and because there is more not mapped information in my POCO classes (which prohibits the approach of updating a correct database and update my classes database first) the only (visible to me) way would be to somehow gather the CREATE TABLE statements a context would create when I call Database.Create() which I can use to update my schema and the update steps accordingly.
I know quite sure I can do the same by logging the context while calling the Create() method, however - this will take quite some time, will issue some queries I do not need and will create a dump database I have to get rid of afterwards each time I update my model.
So I was wondering if there was a way to inspect the modelBuilder (or the context, of course) and somehow see what the tables would look like it maps to.

EF 6.1.3 with "linked server"

I am using the SQL Server 2012 and EF 6.1.3
I have a central database A and another database B which is linked to the database A. The two databases are used for two different applications.
In the database B I have some views which is exactly as some table in the central database A.
What I am expecting is that when I insert/update/delete records in views of the database B, those records will be inserted/updated/deleted in the central database A.
For the application using the database B (this is the linked server, not the central database), I am using the EF to generate views (using power tools). Code generated looks fine, but, certainly, the generated entity doesn't have primary key properties, doesn't have navigation properties as well.
Can you help with a solution?
EF (Power tools) uses the system tables to retrieve the schema and if you run power tools on database A the navigation informations about linked tables cannot be retrieved. Probably the best way could be that you generate the classes for database B starting from database B (deleting same classes generated starting from database A) then mix the two databases.
At the end you mix the two models (adding navigation properties from model of A to model of B and vice versa).
I had a similar situation once, my problem was with a Stored Procedure in database B (I had access to this object via Linked Server in my Central Database, let's call it Database A. It was not possible to map Database B due to a few company policies), EF 6 does not let you map this Stored Procedure in your EDMX file when using the Database First approach, so what I figured out is a way to trick Entity Framework.
It's pretty simple, I just added an SQL Synonym in Database A, this object points to the View/Stored Procedure/Table in Database B (See attached picture)
Of course, I created the synonym for the Stored Procedure in Database B in my case, then in a method I executed the stored procedure like this:
SqlParameter paramNumber1 = new SqlParameter("#firstParameter", someVariable);
//We need to create a class for the Synonym result, which origin is: [Server].[Database].[dbo].[RemoteStoredProcedure]
var result = ctx.Database.SqlQuery<classForTheSPResult>("RemoteStoredProcedure #firstParameter", paramNumber1).ToList();
If you take this approach, you can perform a Raw SQL Query from your synonym View. For further information, check some the MSDN site, the query would look like this:
using (var context = new BloggingContext())
{
var blogs = context.Blogs.SqlQuery("SELECT * FROM dbo.Blogs").ToList();
}
I hope my comments have been helpful.

Does SQL Table name === Class name? and vice-versa?

So I'm just learning Cache, and have a question about tables, classes and globals, what's the difference?
I'm doing the tutorial and it seems like, since this is an object-orientated DB that a class is a table and vice versa. So if I create a class and make it persistent with properties, I can use SQL to query it. Is this true? What's a global then?
Reason I ask is because I'm using Management portal for one of our Cache applications and although I can see a table in WinSQL and Documatic, that same table doesn't seem to exist in the class explorer (Under management portal)... can't figure it out, is it hidden? Is there a command to see class def'ns in terminal??
thanks!
In Caché, classes are tables and tables are classes. You can choose when you want to use SQL access and when you want to use Object Oriented access.
Globals are the sparse multidimensional arrays which sit as storage beneath the class/table. Look at the storage definition at the end of your class to see the actual globals that your persistent class is stored in (e.g. ^Sample.PersonD)
By default, class names are projected as table names, but there are some rules which apply in order to ensure that the table names comply with SQL standards:
if you have a class that is a couple of packages deep (e.g. MyApp.Data.Person) then all but the last "." will be replaced by "_" in the table name (e.g. MyApp_Data.Person would be the table name)
You can't use reserved SQL keywords in table names, so if you make something in the User package for example (class: User.Person) then Caché will change the Package name (e.g. SQLUser.Person would be the name of the table)
I suggest you refer to http://docs.intersystems.com/cache20141/csp/docbook/DocBook.UI.Page.cls?KEY=GORIENT_ch_persistence for more detail

Generic way to insert some data into a table

I have always been using nhibernate ORM for inserting data to sql tables from application.
But recently I tried reading on Ado.net and found suggestion to use stored proc instead of
sqlcommand.executenonQuery().
In that case, every table insertion will need a different stored proc . A 100 table application will need 100 Stored procs. Is my understanding correct or is there a better way of doing it in a more generic way?
Please suggest.
A simple one-liner command can be an INSERT given directly in .NET code via parameterized Command class. Something like:
using (SqlConnection sqlConn = new SqlConnection(connectionString)) {
using (SqlCommand sqlCmd = new SqlCommand("INSERT INTO MyTable (Field1, Field2) VALUES (#Param1, #Param2)", sqlConn)) {
sqlCmd.Parameters.AddWithValue("#Param1", someValue1);
sqlCmd.Parameters.AddWithValue("#Param2", someValue2);
sqlConn.Open();
sqlCmd.ExecuteNonQuery();
}
}
So it doesn't have to be a stored proc for every command. You can have a class or classes dedicated to DB access only (db access layer) and populate it with various methods to read/write from DB. You can even have a generic method that automatically derives parameters for INSERT/UPDATE commands.
Of course if it's more than 1-2 commands or some logic is involved - that asks for a stored procedure.
Btw, this is my personal opinion, but i think ORMs are evil.
Have you heard about dapper, a powerful tool to execute a query and map the results to a strongly typed List. Dapper also support stored procedures, check this out.
Example:
dbConnection.Query<return type>("yourSP", parameters,
commandType: CommandType.StoredProcedure).First();
Also take some time to check this SO question.
Personally I would use an ORM if I have more than 5 different tables to select and/or insert into. Why should you walk 100 miles if the bus stop is right infront of the door?
That said the ORM is a generic way to access data. If you would want to code everything by hand, you could surely write stored procedures with optional parameters, but I don't recomend it.

Change Schema of Entity Framework

I'm using Entity Framework 5 on ASP MVC 4 web site I'm developing.
Because I am using shared hosting which charge for the number of databases I use I would like to run a test site near my production site.
I have two problems:
1) I use Code First and Database Migration. The migration classes seem to embed the schema dbo inside the name of the tables.
How can I change the schema according to the test/production flag
2) How can I change the schema from which EF select data?
Thank you,
Ido.
Both migration and EF take schema from mapping so if you want to change the schema you must update your mapping to use:
modelBuilder.Entity<MyEntity>().ToTable("MyTable", "MySchema");
and control the value of MySchema from configuration but this is really bad idea. One day you forget to change the value and break your production. Use local database for development and test.
As already said: use identical databases (structurally) for development, test and production.
The goal of schemas is to group database objects, like we do with namespaces in e.g. C#, or to simplify permissions for groups of database objects. Not to identify database stages. By using them for the latter you also make it much harder, if not impossible, to use schema appropriately. See for instance this MSDN white paper.
It is much easier to use some database name conventions to indicate their purpose.