SSDT + LinkedServer = Heterogeneous queries require the ANSI_NULLS and ANSI_WARNINGS options to be set for the connection - linked-server

If anyone can assist with this issue, I’d be most grateful. I’ve been struggling with it for too long now, and can’t seem to resolve.
I have an SSDT project (VS2012, SQL2008) with stored procedures that
reference a linked server.
The project builds successfully
When attempting to deploy, with either (localdb) or “regular” SQL
Server, using either F5 or Schema Compare, deployment fails because the linked server isn’t defined in the target
After defining the linked server, the project still fails to deploy
any stored procedure that references the linked server with:
Error 200 SQL72014: .Net SqlClient Data Provider: Msg 7405, Level 16,
State 1, Procedure usp_MemEligGetFullData, Line 157 Heterogeneous
queries require the ANSI_NULLS and ANSI_WARNINGS options to be set
for the connection. This ensures consistent query semantics. Enable
these options and then reissue your query.
Adding SET ANSI_NULL ON and SET ANSI_WARNINGS ON to these stored procedures doesn’t help, nor does selecting the corresponding checkboxes in the database settings of the project properties.
This is a blocking issue for an entire team in an enterprise environment, so again, if anyone has any ideas about why this is happening, I would most appreciate it!

In Visual Studio,
right click the stored procedure
Click on properties
Change ANSI Nulls to 'On'

Try creating the stored procedure through SSMS, but executing SET ANSI_NULLS ON and SET ANSI_WARNINGS ON in a batch immediately preceding the create procedure statement, like so:
SET ANSI_NULLS ON
SET ANSI_WARNINGS ON
GO
CREATE PROCEDURE usp_MemEligGetFullData AS /* stuff */
If that's successful, then check whether the script generated by SSDT also contains those set statements before the create procedure statement. If it doesn't, then ensure that you have the Script Database Options setting enabled. If it still doesn't, then in the worst case you could author a deployment contributor to modify the TSQL that gets generated.

Related

Setting a relative path to sqlite database with Delphi and Firedac

In replacement of my previous question which was confusing and poorly formulated, here is the "real" question.
I would like to known how to set, with Firedac, at runtime, a relative path to a sqlite database located in a subfolder of my application folder.
As Jerry Dodge stated :
Any application should never rely on writable data in the same directory anyway. Also, even if you did, you should make sure all your paths are relative to the application at least.
At the moment, the application I have in mind is portable and I would like the database file to be stored in a sub-folder of the main exe folder.
On the Form.Create event of my main form, is used first
path := ExtractFilePath(Application.ExeName);
And in then for FDConnection :
with FDConnection1 do begin
Close;
with Params do begin
Clear;
Add('DriverID=SQLite');
Add('Database='+path+'Data\sqlite.db');
end;
Open;
end;
I keep on getting an error saying "unable to open database file".
I don't want to set the path to the database file in the FiredDac Connection Editor because then it would be absolute and bound to my machine, right ?
How could I set this path to the database file so that it would work in any configuration, wherever the user puts the application folder ?
Thank you all in advance
Math
As I found my own solution, I decided to post it here for future users who might encounter the same problem (that is to say a Delphi beginner level and the need to link a database file relative to their project exe file).
FIRST STEP was to add a data module to the project. This was done by going to File -> New -> Other -> Delphi Files -> Data Module
SECOND STEP Once the data module added to the project, as my main Application Form makes a call to the database on creation, I had to make sure the Data Module was created first. To achive that, I went to Project -> Options -> Forms and dragged the datamodule in first position of the list of auto created Forms
THIRD STEP was to drop a FDConnection on the datamodule and set all parameters EXCEPT database file.
FOURTH STEP was to add an OnCreate event to the datamodule, to specify the path to the database relative to the application exe and connect. It was done like this :
procedure TDataModule1.DataModuleCreate(Sender: TObject);
begin
path := ExtractFilePath(ParamStr(0));
FDConnection.Params.Add('Database='+path+'Database\sqlite.db');
FDConnection.Connected := True;
end;
FIFTH AND FINAL STEP was to add the datamodule to the uses clause of all other units that needed a connection to the database.
I realize that this solution is far from perfect and that, as very experienced users already stated, storing the database in the same folder (or a sub-folder) as the main application Exe is not a good solution.
Also, I decided to connect to the database on DataModule creation, but another solution could be to connect on demand before triggering the queries and then disconnect. That's up to you and your needs
Thanks to all for your help, tips and advises
Math
PS : please notice I did not check my answer as accepted as the best answer, would not be fair right :-)
Introduction
IMHO
Database path and server name should not be hardcoded in applivcation.
Why ?
When you work on a project, you need to do many things on database connection, setting datasets, query etc. Usualy this is done on working database. Then server name and database path are different from those of the real database.
You should be able to set up server name and path to database easy and without to compile the project. This allows to set properly database connection params on a random computer.
Solution :
Setup the database connection component on design time, do not create it in runtime. Setup all parameters including server name , database path, charset etc. to your working copy of database. This will allow you to set up the other components associated with this database on design time.
(In your answer I see you have done almost the same.)
Save server name, database path and any other parameter you want, to an exterrnal resource, ini file, windows registry or something else. Then get these parameters when application started or before connect to database.
In your case, you use local server and the same path as application, so you don't need to store nothing.
Regarding the question
The code :
with FDConnection1 do begin
Close;
with Params do begin
Clear; <-- this removes all parameters
Add('DriverID=SQLite');
Add('Database='+path+'Data\sqlite.db');
end;
Open;
end;
removes all other parameters except DriverID and Database. Probably the error arise from that.
If you already setting all parameters in FDConnection:
Do not use:
FDConnection.Params.Add('Database='+path+'Data\sqlite.db');
This will add new parameter with the same name, but connection will use the first one.
This explains why everything works in your answer, because you did not set a parameter 'Database' on design time:
THIRD STEP was to drop a FDConnection on the datamodule and set all
parameters EXCEPT database file.
Instead use :
FDConnection.Params.Database := 'Database='+path+'Data\sqlite.db';
You may use this for example in
OnDataModuleCreate or FDConnectionBeforeConnect events
I hope this will be useful.
In android, I couldn't compile with fdConnection opened in design time, then certify it's closed. Your first line didn't work for me, but about takes the goal:
using following expression, it works for me:
FdConnection1.Params.Values['Database'] := GetHomePath
+ PathDelim + 'sqlite.db';
Look that I didn't use subfolder 'Data'. You can try simple first.
If your resources are light and read-olny for end-user, you could pack them direct into exe file. This would give you really portable application, which your user can run from arbitrary place, even from usb flash.
Go to Project->Resources and Images menu, add there you files.
You can access them in runtime with TStream:
var
s: TStream;
{.....}
s:=TResourceStream.Create(hinstance, 'myfile_1', RT_RCDATA);
Some resources you can handle direct in memory. As for sqlite database, you could copy it from app resources to user's documents path:
MyAppPath := Tpath.GetDocumentsPath+'\MyAppName'; // you need System.IOUtils in uses
If not DirectoryExists(MyAppPath) then CreateDir(MyAppPath);
MyDBPath := MyAppPath+'\Data\sqlite.db';
If not FileExists(MyDBPath) then begin
FL:=TFileStream.Create(MyDBPath ,fmCreate);
FL.CopyFrom(s,0); // this will copy your db into 'sqlite.db' file
end;

How to debug a trigger in SQL Server what is executed by an ASP Web app?

Context:
I have a (legacy) ASP.NET app using a class lib which's data access is calling SPs using ad dal.dbml and its generated code.
I am using VS 2015 Enterprise update 1, have locally installed Microsoft SQL Server 2014 - 12.0.4213.0 (X64) (Build 10586) and SSMS 2014.
Question
When running the Web application the app inserts rows to a table which I recently implemented an insert trigger. How can I debug the actual trigger execution "triggered" by the Web application?
Note: I do know how to interactively debug SPs in SSMS. Now that is not I want, because It is nearly impossible to reproduce and parametrize what the web app does. So I would like to debug via the Web App.
Is this possible at all? (Seems to be a pretty usual need, though I unserstand it requires very complex debugging infrastructure and services)
What you do is you run Profiler to get the typical values being sent when the error occurs.
Then the easiest way I know of to troubleshoot something like this is to take the trigger code out of the trigger and put it in a script using #inserted (and/or #deleted if need be) instead of the pseudotables accessed by the trigger.
The insert the data the stored proc would insert into the table into the #inserted table. Then you can take the trigger step by step and even look at the results of a select that is used in an insert.
The most common error I have found in triggers is that they are set up to handle only one record in inserted rather than multiple records. SO if you find that what your proc would put in for the values you get is one record, that may be the issue. Or you may be missing a required field. IN that case you may need adjust the proc to put in the value or assign a default.

How to Alter a Trigger in SSDT

I am a C# developer, and would rather use VS 15 and SSDT than SSMS.
However, I don't understand how I should be doing an "Alter Trigger..." script.
For example, In Sql Object Explorer, I select Design, and the Designer opens. I then click on the trigger on the right hand side, and it displays a create script for the trigger.
However, I don't want to create it, I want to alter the existing one. So I change "create" to "alter", thinking that should run. However, an error is thrown:
This statement is not recognized in this context.
Should I be using SSMS for this type of activity?
The only workaround I could come up with is changing the name of the existing trigger, and then running the create statement instead of an alter statement.
I am just wondering what the workflow is supposed to be on this.
When you deploy an SSDT project it takes the model in the SSDT project, compares it to the database and then automatically generates the upgrade script.
So what you do is write "create trigger" and publish your database and the upgrade will either drop and create the new one or do an alter for you.
If you haven't deployed to your database yet I would suggest generating a script rather than publishing it and verifying what is in there first. :)

SSDT Publish errors on Creating Publish Preview

I am using Visual Studio 2013 to manage a .sqlproj file containing our database schema. The schema has been deployed successfully dozens of times.
When attempting to publish to one specific target database, the "Creating publish preview" step appears to fail, but no error is given. The output from the preview includes some expected warnings:
The column {...} is being dropped, data loss could occur
If this deployment is executed, changes to {...} might introduce run-time errors in {...}
This deployment may encounter errors during execution because changes to {...} are blocked by {...}'s dependency in the target database
I have unchecked "Block incremental deployment if data loss might occur".
The Preview just stops, and no script is generated.
This happens when there exists a stored procedure (or view or constraint or other object) in the target database, that isn't included in your sqlproj, that references a table that would be altered by deploying your sqlproj. SSDT apparently can't determine whether the change is safe unless the referring thing is included in your sqlproj, and then it errs on the safe side by blocking the deployment.
Disabling the "Block incremental deployment if data loss might occur" option only relaxes the data-loss checks. There isn't a "Block incremental deployment if run-time errors might occur" option.
You have three options:
add whatever stored procedures, views, or whatever from the target database to your sqlproj
uncheck the "Verify Deployment" option in the ssdt publish options (this is dangerous unless you're aware of the other referring sprocs and know that they aren't going to break)
if you're certain that everything that should exist in the target database is contained in your sqlproj, you can enabled the "Drop objects in target but not in source" option
The issue may also be caused prepending a database object with the wrong schema. For instance a table being referenced within a stored procedure SQL statement and the table being prepended with an incorrect schema name.
Additionally, we had some permissions for a specific security group that once we removed the solution would build again. In order to troubleshoot the error perform a schema compare of the project code and the target database. Remove differences from the database until the publish functionality works. The last item that you removed from the database is your culprit.
The last warning pattern appears to be more than a warning:
This deployment may encounter errors during execution because changes
to {...} are blocked by {...}'s dependency in the target database
appears to have been the culprit behind stopping the rest of the preview and the generation of the script.
Interestingly, the schema change being introduced would not have broken the triggers referenced in the preview output.
removing schemabinding from the view allows the publish to succeed with only warnings

How to work with LocalDB and EF, without using migrations

I am on VS 2012 RTM, with EF 5. I am doing Code First, but trying to ignore Code Migrations since I am just in development. To avoid them, I have this set
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<SomeContext>());
Occasionally, even when I don't think I've touched the model, it decides to recreate. That's fine. But it usually results in the error
Cannot drop database because it is currently in use.
So I decided to delete the database entirely. I go into VS, go to the "SQL Server Object Explorer", find the DB and delete it. Now I'm stuck at
Cannot attach the file '{0}' as database '{1}'
I had this happen last night and I just fiddled around until it work (shut down tasks, restart VS, changed the DB and file names in the web.config, etc.
So question 1) How do I get out of this state?
But the more important question, how do I prevent myself from getting in this state at all?
The SQL Server Object Explorer window can hold a connection to the database. Closing the window and all windows opened from it releases the connection.
I had the same problem and managed to fix it. The main problem is that EF won't automatically create the database. The solution is not very hard.
First, go to the Solution Explorer and manually create the database. To do this, go to the folder where your database is located (usually App_Data). Right-click on this folder and click on Add -> New Item. Select the Data tab and select SQL Server Database. Make sure you enter the name Entity Framework expects (which is specified in the Cannot attach the file '{0}' as database '{1}' error message).
Then most likely you will get an error message that says that the database does not contain any model metadata. To circumvent this, change your database initialisation to:
Database.SetInitializer(new DropCreateDatabaseAlways<SomeContext>());
Now run the application and the database should be there with tables correctly created. Once this step has been successfully executed, you change change your database initializer back to:
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<SomeContext>());

Resources