I have an Azure SQL (S3) geo-replicated read-only database.
My problem is that when I query the Read-only from VisualStudio I can see the Query is hitting the Master database.
I expect the Query to hit the Read-only database.
But if I run the same Query from SMSM connected to Read-only then I can see the Read-only database is hit. This works as expected.
To see the last Query in each database I use following SQL.
SELECT execquery.last_execution_time AS [Date Time], execsql.text AS [Script] FROM sys.dm_exec_query_stats AS execquery
CROSS APPLY sys.dm_exec_sql_text(execquery.sql_handle) AS execsql
ORDER BY execquery.last_execution_time DESC
Question
Why is my c# (entityframework 6.0) code not showing in the Read-only database?
Background
The goal is to have a read-only SQL to handle the external API load so the Master SQL is not to load.
In Azure Portal, I created a Geo-Replication SQL in the same region as Master.
The connection string is set to Read-only database.
I tried[ApplicationIntent=ReadOnly] flag in connectionstring with no success.
The problem was old format on the connectionstring "User ID".
I used "username#server". The #server was pointing to the server of Master Sql.
I changed to only "username" and now it works.
Related
At our workplace, we have an ASP.NET application that uses Microsoft SQL Server 2016 Web Edition Database Server for the back-end database.
At first, In the ASP.NET application web.config, I configured the Database Connection String to be:
Password=blahPasswordblah;
Persist Security Info=True;
User ID=sa;
Initial Catalog=yadaDatabaseNameyada;
Data Source=blahDNSServerNameblah\yadaSQLServerInstanceNameyada
It seemed to connect properly. However, I noticed something strange when the code in the ASP.NET application would try to query a particular view. The query would return an empty result set.
However, when I changed the connection string to include the workstation id and the application name:
Password=blahPasswordblah;
Persist Security Info=True;
User ID=sa;
Initial Catalog=yadaDatabaseNameyada;
Data Source=blahDNSServerNameblah\yadaSQLServerInstanceNameyada;
workstation id=blahWorkStationIDblah;
application name=blahApplicationNameBlah
the query on the view in question would return the proper data that I expected.
Here is the metadata about the view:
USE yadaDatabaseNameyada;
SELECT *
FROM INFORMATION_SCHEMA.VIEWS
WHERE table_name = 'blahViewOfInterestblah'
TABLE_CATALOG
yadaDatabaseNameyada
TABLE_SCHEMA
dbo
TABLE_NAME
blahViewOfInterestblah
VIEW_DEFINITION
Create View dbo.blahViewOfInterestblah ..........
CHECK_OPTION
NONE
IS_UPDATABLE
NO
Why does the query on the view in question return the actual proper results when I include the workstation id and the application name in the Database Connection String?
The reason why I’m asking is because when we ultimately deploy the ASP.NET application to production, it would be poor practice to have a “workstation id” attribute and the "application name" attribute in the Database Connection String.
Why won't it work withOut the “workstation id” attribute and the "application name" attribute?
Though this is an old question, I was looking for info on this very subject, so as a partial answer to this question, and without knowing more about the configuration of the database, server and application user account, here's my brief answer:
According to Microsoft, both Application (APP) and Workstation ID (WSID) are optional:
APP Name of the application calling SQLDriverConnect (optional). If specified, this value is stored in the master.dbo.sysprocesses column program_name and is returned by sp_who and the APP_NAME functions.
WSID The workstation ID. Typically, this is the network name of the computer on which the application resides (optional). If specified, this value is stored in the master.dbo.sysprocesses column hostname and is returned by sp_who and the APP_NAME and the HOST_NAME function.
Have you tried changing the privileges of the application SQL user or adding them to the DBO role?
My query is when I install this application on some system with SQL Server install I should get all databases in a combobox.
Login image
In the first combobox (Select database type) we have option to select the SQL Server. When I will select the SQL Server, I wish that the available instance of the database like root or something else should come in second combobox. And we should get the database name of the all database in the 3rd combobox
To list the instances of Sql Server you can use:
SQLCMD -L
By executing it in a process and collect the output.
For listing of the databases you can use this select statement:
SELECT name FROM master.dbo.sysdatabases
or
EXEC sp_databases
The problem is, you need to be logged in to the database to get the list of databases which the logged in user is allowed to see. I think you need to consider it in your application.
I am trying to copy all table data from server to my local database, like
INSERT INTO [.\SQLEXPRESS].[Mydatabase]..MYTable
SELECT *
FROM [www.MYSite.com].[Mydatabase]..MYTable
www.MYSite.com having SQL LOGIN ID XYZ AND PASSWORD 1234
but I get an error:
Could not find server 'www.MYSite.com' in sys.servers.
Verify that the correct server name was specified. If necessary,
execute the stored procedure sp_addlinkedserver to add the server to sys.servers.
I want to copy all the data from Mytable of www.MYSite.com to Mytable of .\SQLExpress.
How to resolve it? Please help.
Update :
I am using Microsoft Sync Framework 2.0 to sync all data from www.MYSite.com to .\SQLExpress and vice versa, but in a one condition I want to copy data from www.MYSite.com to .\SQLExpress without sync framework
Please Note I am passing those SQL Statement using C#..
When you specify a database on another server, like this:
SELECT *
FROM [www.MYSite.com].[Mydatabase]..MYTable
... the server name needs to be one that the database server was previously configured to recognize. It needs to be in the system table sys.servers.
So, you need to configure your SQLExpress instance to "know about" that server.
You can do this in code, with the stored procedure sp_addlinkedserver. You can learn more about it here.
Or, you can do it through SSMS:
I hope the below information will help you:
Using SQL Server Management Tools you can use the Import Feature.
Connect to your SQL instance server.
Select your database schema.
Right click Tasks > Import.
and follow wizard instructions.
I'm trying to retrieve records to my data gridview dgvEmployees from my table tblEmployees. I'm not sure what's wrong though, maybe because of the syntax? But the code has worked before using MS Visual C# 2010 Express (WinForms only). I'm currently creating a webpage with winforms using MS Visual Studio (ASP.NET - C#). Here's my code:
SqlConnection sConn;
SqlDataAdapter daEmp;
DataSet dsEmp;
const string sStr = "Server = MYSERVER\\SQLEXPRESS; Database = EMPLOYEES; Integrated Security = SSPI";
protected void Page_Load(object sender, EventArgs e)
{
sConn = new SqlConnection(sStr);
daEmp = new SqlDataAdapter("Select * from tblEmployees", sConn);
dsEmp = new DataSet();
daEmp.Fill(dsEmp, "tblEmployees");
dsEmp.Tables["tblEmployees"].PrimaryKey = new DataColumn[] { dsEmp.Tables["tblEmployees"].Columns["EmployeeID"] };
dgvEmployees.DataSource = dsEmp.Tables["tblEmployees"];
}
Here's the error message on this line (daEmp.Fill(dsEmp, "tblEmployees");
Invalid object name 'tblEmployees'
Please help. Thanks!
The error is referring to the SQL query not the DataSet. In other words the issue is not with the C#. You need to check your connection string and make sure the table exists in the DB.
daEmp = new SqlDataAdapter("Select * from tblEmployees", sConn);
This query is bad: Select * from tblEmployees
You can verify this by changing the query to: Select * from IDONTEXIST
You will see a similar error:
invalid object name IDONTEXIST
You are now running the application on the website so the user that will connect to SQL server is the one that is running your application pool in IIS when you use Integrated Security = SSPI in your connection string.
You need to either:
Give access to the database for the application pool user (not a good idea for the default one).
Change the user for the connection pool to a user who has access to the database.
Specify a user who has access in the connection string.
You should first verify your connection string:
Ensure it is connecting to the SQL Server instance you think it is.
Ensure that it is establishing the database context for the connection in the database you think that it is.
Ensure that it is connecting with the credentials you think that it is.
Ensure that those credentials map to the SQL Server user you think that it should
That that SQL Server user has the default schema you think it does and that it has appropriate rights granted in the database.
Almost certainly, your problem derives from one or more of the issues listed above.
If your database context for the connection is in a different database than you think, you probably won't find the objects you're looking for.
If your object references are not schema-qualified, you may have a problem resolving object references. Object references in your SQL queries should always, at the very least, be schema-qualified. Instead of saying
select * from tblEmployees
you should be saying
select * from dbo.tblEmployees
where dbo is the schema that owns the object. Any object references that are not schema-qualified are looked up at run time in the following order
First, the current user's default schema is probed for an object of the desired name.
If that fails, the dbo schema ('data base owner') is probed for an object of the desired name.
For stored procedures, the lookup is more complex:
Probe the current user's default schema in the current database.
Probe the 'dbo' schema in the current database.
If the stored procedure name begins with 'sp_',
Probe the current user's default schema in the 'master' database.
Probe the 'dbo' schema in the 'master' database.
If the object in question belongs to another schema, it will not be found unless qualified by the owner schema.
Due to the multiple lookup issue, lack of schema-qualification can prevent execution plan caching, meaning that the query plan has to be recompiled on every execution of a query. Needless to say, this has...sub-optimal effects on performance.
Further, you may get...interesting...results if your database user is 'dev' and the dev in question, 6 months back, created a table or other object named 'dev.foo' during development. Now you're live in production and connecting as user 'dev'. Executing select * from foo will bind to dev.foo in preference to the actual production table that the DBA created, 'dbo.foo'. Your users will be wondering why their data is missing or you'll be ripping your hair out wondering why the app is whining about missing columns when they appear to be all there when you look at it via the SQL Management Studio.
With SQL Server I run this query with no problem...
SELECT SUM(Esi) AS Dispo
FROM [mdb].[dbo].[Query1] AS A
INNER JOIN [mdb2].[dbo].[TieCol] as B ON A.Alias=B.IDAlias
WHERE Alias LIKE 'SETUP%'
I join two tables that reside in two different databases (mdb and mdb2).
But how can I do it in my .NET application?
When I need to use this statement
string cmdText = "SELECT SUM(Esi) AS Dispo
FROM [mdb].[dbo].[Query1] AS A
INNER JOIN [mdb2].[dbo].[TieCol] as B ON A.Alias=B.IDAlias
WHERE Alias LIKE 'SETUP%'";
this.OP = new SqlConnection(ConfigurationManager.ConnectionStrings["mdb2"].ConnectionString);
SqlCommand sqlCommand = new SqlCommand(cmdText, this.OP);
I can't execute it, since this.OP is the connection to mdb2... And for mdb?
How can I connect to both databases simultanously?
The SQL connection is to the server - the Initial catalog in a connection string behaves like use - it sets the default DB.
So your 3 part SQL query should work as is. So possibly
Make sure that the SQL login used by your app (or the account of your AppPool if using Web and Integrated Security) has the necessary access to both databases. (use RunAs on SQL Enterprise Manager as this account and try to run the query)
You might try escaping [Alias]
Also, if there is coupling between mdb1 and mdb2 (e.g. SPROCS in mdb1 use tables in mdb2 etc), for ease of maintenance, you might consider adding views in mdb1 for mdb2 objects. This allows for easy identification of cross-database dependencies. In this case, your query can use views which look like they are in the same database, although the underlying dependency on mdb2 is still there.
I'm not sure if there is a way to do this within the connection string. But you can probably do it using a four part reference to the table: [server].[database].[table].[column].
Your C# application only need to connect to one database server for this query.
Say your C# application connect to [mdb]. Database [mdb2] should b linked server in database [mdb].
Since you can run that query in sql server, so there must be one sql server connected to both databases. use that sql server in your C# connection string. That's it!