Getting around cyclical foreign key errors when trying to generate insert data scripts in SQL 2008 - sql

I am trying to generate some insert scripts using the SQL Server 2008 Script Wizard. Upon generating the scripts, I get the following error:
"The selected database contains foreign keys that create a cycle. Publishing data only is not supported for databases with cyclical foreign key relationships."
I've attempted to disable and remove all constraints in the database. The error is still occurring. Is there any way to get around this? Possibly make SQL ignore the constraints while generating the scripts.

On the Wizard page where you choose the radio button to select All Database Objects or Specific Objects, make sure to select All Database Objects. For some reason the tool needs something in there to generate even if you just want the table insert script.
Once I changed that radio button to All Database Objects, and selected the Advanced option to generate Type of script = Data Only, it worked all the way through.

I had the same problem as the OP. Then I tried again, this time in the advanced options, for the "types of data to script" option, I selected "schema and data" rather than data only. Then it worked for me without complaining about cyclical keys.

I was having the same issue, and I discovered today that you can use SQL Server Management Studio 2012 against a 2008 R2 DB and you won't get the error:
Sql Server Scripting Data Only: Workaround for CyclicalForeignKeyException?

Saving to file vs. to a new Query editor window seems to make it work for me on Management Studio 2008 :\

First off IMHO HLGEM's response is a bit cavalier--there are valid reasons at times to have cyclic references.
That said I think the script generator is hyper-sensitive. It seems to think just about any PK/FK pair is "cyclic" and I ended up having to use a copy of my database from which I'd stripped all keys to get the export to get beyond the "cyclical" error. A script like the following can help you drop keys globally but of course be careful!
SELECT
'ALTER TABLE ' + object_name(parent_obj) + ' DROP CONSTRAINT ' + [name]
AS Script
from sysobjects where xtype IN ('F')
[I didn't write this. See http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=46682]
Further the tool is pretty useless in terms of feedback since its report doesn't provide enough detail to narrow down where the supposed cyclical references exist.
Finally I found the tool to be pretty flaky in that I get random timeouts. One other observation that I haven't researched extensively is I think the tool may require you to start from scratch after the cyclical error to clear it's cache since I see different behavior when I use Previous button vs. starting afresh.

You can export the data by setting the script option - "Script Check Constraints" to False
Sorry this will not work :(
You will have to determine which table is causing the issue.

I was getting the same error because I didn't had a table selected in the object list (one big table I wanted to create in another script). Selecting all of the tables solved the problem.
PD: Maybe a little bit late, but searching CyclicalForeignKeyException gets first in Google.

Related

How to copy from table design from database to another vb.net access

The aim is when updating the application and update the access database without altering the data so update by update only the new tables or new columns so i want to copy the exact table with it's structure to the old database vb.net and access database.
what I've tried is detecting the differences between the old database and the new one by getting in combobox1 the only missed table and in combobox2 the missed columns in the old database in exact table already there in both database and get it's data type .
so i want to copy the entire table and then create only missed columns
thank you
There is not a built in tool to do this.
But, worse yet, there is no "generate" change scripts in Access
(Like say with SQL server).
So, how do you approach this issue? What do some of the accounting systems or commercial programs that use ms-access as the database?
Well, you have to build a kind of "up-grade" system in your software.
This means two things:
To add a new column to a table (for example), you NEVER go open up the access database with access, but "add" or "write" the code to add that field in question.
In fact, I had an applcation deployed out in the field - many desktops.
So, I had a code module called upgrade. And each time I needed a new field or whatever, then I would write the code to add that new colum.
AS LONG as I always added things into that code module, I was ok. (never break the rule for adding new fields, tables or even increasing the length of some field? - use code).
And it became quite easy after I had some code written. I would in fact often cut + paste a previous bit of code to add a new column to a table.
However, after about 5 years, that messy code module had 800+ lines of code in it!!!
But, I ALSO realized that MOST things like adding a new column or whatever? Same code over and over.
So, what I did next was built a "upgrade" table. It looked like this:
Version action SQL RunCode
2.5 AddTable tblCustomers
2.5 AddField "sql here to add table"
etc. etc.
So, I had a version number, and then I compare against the up-grade table. I had "action", and the code would simple loop this table, and do whatever.
So, for example, to add a field, you can use access "DDL" command (data definition commands - most SQL systems support this, and so does Access).
so, say like this:
' any new table code goes here:
If lngVer < 1148 Then
' add event Invoice text option
ExecuteSQLNR "ALTER TABLE dbo.Events ADD InvoiceText ntext NULL"
ExecuteSQLNR "ALTER TABLE dbo.Events ADD HideEventDate bit NULL default 0"
Or, say to increase a column lengh from 50 to 55
db.Execute "ALTER TABLE tblGroupRemind ALTER COLUMN Anotes text(255)", dbFailOnError
As noted, since oh so many the commands were VERY similar, then I started putting that information into a table, and then I would execute the required upgrades in a loop.
For a whole new table? Well, I thought that was too much code, so I always included a blank empty database - and for new tables, I would place them in that upgrade.accDB table - and "transfer/copy" the table from that upgrade database to the real one. That way, I could with great ease create a whole new table, and create in Access designers, and then add/copy that table to the "upgrade.accDB" database.
As noted? The above ideas an approaches work quite well.
In fact, over time, I found it LESS hassle while coding away to add the new column or whatever LESS effort then having to open up ms-acces, and then the table, and then the designer and make the changes.
However, the BIG issue with above?
Well, you have to get all users at least upgraded to your EXISTING schema, and there is no automated tools.
in fact, before I had any automated tools? I would open up note pad, and if I added some field to some table? I would simple type into note pad that new field in such and such table is required).
Then, when on customer site, I would open up their database, and then go look at the note pad document for the list of changes I was to make. (that is what I was doing before I started automating the process - and of course it not always practical to be "on site" or have the customers database.
But, ONCE I had all of the above working?
Then during development, I would open up my "upgrade" database, add the new row and action (new table, new column, (and more).
I even had a column that defined the function to run AFTER that one command. I mean, quite often when you add a new column, or change somthing in a table, often you need to copy data, or at least process some data after you make that change.
Once you get above going?
Then you simple NEVER make changes in the data tables directly, but use your "system" for this. And that works REALLY well.
For one, a customer could open up a older data file - say one from 4 or 5 years ago. The applcation version number would be detected, and then the upgrade code would run all though the versions to update that database. (and I did this automatic on startup - so they never even knew such a upgrade had occurred).
So, you just have to make sure that for each change you make, you put that code in your upgrade system, and you are done.
But, for existing systems? You have to look at what changes you made since last deploy, and write out the "ddl" commands (the alter table SQL commands).
There is no automated way of doing this.
As FYI?
One of the BEST and more valuable free tools in Visual Tools is the SQL server compare utility. It will not only automatic detect and tell you the changes between two SQL server databases, but will also upgrade for you. (very nice).
But, such a system is not available for Access. In fact, so valuable is that utility for SQL server, you might consider upgrading from Access to SQL server for this applcation. With that utility? I can work local, add fields, columns, tables and even stored procedures to that SQL database. When I am on site (or even by VPN), then I run that compare tool - it shows the changes, and ALSO has a button to update the target schema.
I don't know of a automated "schema" checker and updater for Access.
So, what I suggest for above ONLY works if you put such a system in place, and THEN as a developer always make your schema changes to your upgrade system, and never directly in the database with ms-access.

How to use this weird .sql file?

I have a very strange 'reload.sql' file that I need to use to build a database.
It references about 200 XXX.dat files with straight-up readable data (although useless without explanations regarding the meaning of the fields).
I have tried msssql server, mysql workbench (on a server local-hosted on wamp), and directly accessing it through DBeaver and IBConsole, but I cannot manage to execute/build it.
It uses a weird syntax. There are elements like
begin
...
end
go
that hinted me towards T-SQL, but using sqlcmd on it gave me thousands upon thousands of errors regarding keywords.
Specifically, the very first batch of executable lines says
SET OPTION date_order = 'YMD'
go
SET OPTION PUBLIC.preserve_source_format = 'OFF'
go
SET TEMPORARY OPTION tsql_outer_joins = 'ON'
go
SET TEMPORARY OPTION st_geometry_describe_type = 'binary'
go
SET TEMPORARY OPTION st_geometry_on_invalid = 'Ignore'
go
SET TEMPORARY OPTION non_keywords = 'attach,compressed,detach,kerberos,nchar,nvarchar,refresh,varbit'
go
which generates about 150 errors 'Incorrect syntax near OPTION keyword' on its own, and according to google is part of a 'rexx' procedure but 'date_order' should then be 'DATFMT', right?
Another track is that of SyBase, but I cannot for the life of me get it to work (through my trials I did manage to build a .db file, that, well, is useless to me since I can't build it either..).
I've tried accessing it through ODBC pilots as well but none worked (the paradox ODBC did not crash, but said there was an error with a FROM clause, which are generated automatically...).
I need to know a way to build a database from this file or directly access the data it references, which I can't really post since it contains private medical data.
Also what madman came up with this.
The very first google link (for me anyway) against 'st-geometry-describe-option' shows this is a SAP SQL Anywhere database i.e. http://dcx.sybase.com/1200/en/dbadmin/st-geometry-describe-option.html
So I would suggest starting from the SQL Anywhere documentation and you will need to install the database software beforehand.

Renaming a column without breaking the scripts and stored procedures

I want to modify a column name to new name present in a table
but here problem i want to manually modify the column name present in Triggers or SP's.
Is there a any better way of doing it.
To rename a column am using this
sp_RENAME 'Tablename.old_Column', 'new_column' , 'COLUMN';
similarly how can i do it for triggers or SP's.? without opening each script?
Well, there are a bunch of 3rd party tools that are promising this type of "safe rename", some for free and some are not:
ApexSQL has a free tool for that, as MWillemse wrote in his answer,
RedGate have a commercial tool called SQLPrompt that also have a safe renaming feture, However it is far from being free.
Microsoft have a visual studio add-in called SQL Server Data Tools (or SSDT in the short version), as Dan Guzman wrote in his comment.
I have to say I've never tried any of these specific tools for that specific task, but I do have some experience with SSDT and some of RedGate's products and I consider them to be very good tools. I know nothing about ApexSQL.
Another option is to try and write the sql script yourself, However there are a couple of things to take into consideration before you start:
Can your table be accessed directly from outside the sql server? I mean, is it possible that some software is executing sql statement directly on that table? If so, you might break it when you rename that column, and no sql tool will help in this situation.
Are your sql scripting skills really that good? I consider myself to be fairly experienced with sql server, but I think writing a script like that is beyond my skills. Not that it's impossible for me, but it will probably take too much time and effort for something I can get for free.
Should you decide to write it yourself, there are a few articles that might help you in that task:
First, Microsoft official documentation of sys.sql_expression_dependencies.
Second, an article called Different Ways to Find SQL Server Object Dependencies that is written by a 13 years experience DBA,
and last but not least, a related question on StackExchange's Database Administrator's website.
You could, of course, go with the safe way Gordon Linoff suggested in his comment, or use synonyms like destination-data suggested in his answer, but then you will have to manually modify all of the columns dependencies manually, and from what I understand, that is what you want to avoid.
Renaming the Table column
Deleting the Table column
Alter Table Keys
Best way use Database Projects in Visual Studio.
Refer this links
link 1
link 2
you can do what #GorDon suggested.
Apart from this,you can also play with this query,
select o.name, sc.* from sys.syscomments sc inner join sys.objects o
on sc.id=o.object_id where sc.text like '%oldcolumnname%'
this will return list of all proc and trigger.Also you can modify filter to get exact list.then it will be very easy for you to modify,manually.
But whatever you decide,don't simply drop old column.
To be safe,even keep back up.
This suggestion relates to Oracle DB, however there may be equivalent solutions in other DBMS's.
A temporary solution to your issue is to create a pseudocolumn. This solution looks a little hacky because the syntax for a pseudocolumn requires an expression. The simplest expression I can think of is the case statement below. Let me know if you can make it more simple.
ALTER TABLE <<tablename>> ADD (
<<new_column_name>> AS (
CASE
WHEN 1=1 THEN <<tablename>>.<<old_column_name>>
END)
);
This strategy basically creates a new column on the fly by evaluating the case statement and copying the value of <<old_column_value>> to <<new_column_value>>. Because you are dynamically interpolating this column there is a performance penalty vs just selecting the original column.
The one gotcha is that this will only work if you are duplicating a column once. Multiple pseudocolumns cannot contain duplicate expressions in Oracle.
The other strategy you can consider is to create a view and you can name the columns whatever you want. You can even INSERT/UPDATE/DELETE (execute DML) against views, but this would give you a whole new table_name, not just a new column. You could however rename the old table, and name your view the same as your old table. This also has a performance penalty vs just accessing the underlying table.
You might want to replace that text in definition. However, you will be needing a dedicated administrator connection in sql server. Versions also vary in setting up a dedicated administrator connection. Setting up the startup parameter by adding ;-T7806 under advanced. And by adding Admin: before the servername upon logging in. By then, you may be able to modify the value of the definition.

SQL71501 - How to get rid of this error?

We're using two schemas in our project (dbo + kal).
When we are trying to create a view with the following SQL statement, Visual Studio shows as an error in the error list.
CREATE VIEW [dbo].[RechenketteFuerAbkommenOderLieferantenView]
AS
SELECT
r.Id as RechenkettenId,
r.AbkommenId,
r.LieferantId,
rTerm.GueltigVon,
rTerm.GueltigBis,
rs.Bezeichnung,
rs.As400Name
FROM
[kal].[Rechenkette] r
JOIN
[kal].[RechenketteTerm] rTerm ON rTerm.RechenketteId = r.Id
JOIN
[kal].[Basisrechenkette] br ON rTerm.BasisrechenketteId = br.Id
JOIN
[kal].[Rechenkettenschema] rs ON rs.Id = br.Id
WHERE
r.RechenkettenTyp = 0
The error message looks like this:
SQL71501: Computed Column: [dbo].[RechenketteFuerAbkommenOderLieferantenView].[AbkommenId] contains an unresolved reference to an object. Either the object does not exist or the reference is ambiguous because it could refer to any of the following objects:
[kal].[Basisrechenkette].[r]::[AbkommenId], [kal].[Rechenkette].[AbkommenId], [kal].[Rechenkette].[r]::[AbkommenId], [kal].[Rechenkettenschema].[r]::[AbkommenId] or [kal].[RechenketteTerm].[r]::[AbkommenId].
Publishing the view and working is just fine, but its quite annoying to see the error message all the time when building our project having all the serious errors get lost in the shuffle of those sql errors.
Do you have any idea, what the problem might be?
I just found the solution. Although I can't read your (what appears to be German) enough to know if you're referring to system views, if so, a database reference to master must be provided. Otherwise, adding any other required database references should solve the problem.
This is described here for system views: Resolve reference to object information schema tables
and for other database references.
Additional information is provided here: Resolving ambiguous references in SSDT project for SQL Server
For me I was seeing SQL71501 on a user defined table type. It turned out that the table type's sql file in my solution wasn't set as build. As soon as I changed the build action from None to Build, the error dissapeared.
I know this is an old question but it was the first one that popped up when searching for the error.
In my case the errors were preventing me from executing the SqlSchemaCompare in Visual Studio 2017. The error however was for a table/index of a table that was not part of the solution any more. A simple clean/rebuild did not help.
A reload of the visual studio solution did the trick.
We have a project that contains a view that references a table valued function in another database. After adding the database reference that is required to resolve the fields used from the remote database, we were still getting this error. I found that the table valued function was defined by using "SELECT * FROM ..." which was old code created by someone not familiar with good coding practices. I replaced the "*" portion with the enumerated fields needed and compiled that function, then re-created the dacpac for that database to capture the resulting schema, and incorporated the new dacpac as the database reference. Woo Hoo! the ambiguous references went away! Seems that SSDT engine cannot (or does not) always have the ability to reach down into the bowels of the referenced dacpac to come back with all the fields. For sure, the projects I work on are normally quite large, so I think it makes sense to give the tools all the help you can when asking them to validate your code.
Although this is an old topic, it is highly ranked on search engines, so I will share the solution that worked for me.
I faced the same error code with a CREATE TYPE statement, which was in a script file in my Visual Studio 2017 SQL Server project, because I couldn't find how to add a user-defined type specifically from the interface.
The solution is that, in Visual Studio, there are many programmability file types, other than the ones you can see through a right-click > Add. Just select New Element and use the search field to find the element you are trying to create.
From the last paragraph of the blog post Resolving ambiguous references in SSDT project for SQL Server, which was linked in the answer https://stackoverflow.com/a/33225020/15405769 :
In my case, when I double clicked the file and opened it I found that
one of the references to ColumnX was not using the two part name and
thus SSDT was unable to determine which table it belonged to and
furthermore whether the column existed in the table. Once I added the
two part name. Bingo! I was down to no errors!
In my case, I got this error when I was trying to export the datatier application. The error was related to the link on a database user. To solve the problem, you need to log in to the server with read rights on system users.
In my case I just double click on the error and it will take me to the exact error on procedure and I noticed that table column is deleted or renamed but in SP its still using the old column name.
If you build an SSDT project you can get an error which says:
“SQL71502: Function: [XXX].[XXX] has an unresolved reference to object [XXX].[XXX].”
If the code that is failing is trying to use something in the “sys” schema or the “INFORMATION_SCHEMA” schema then you need to add a database reference to the master dacpac:
Add a database reference to master:
Under the project, right-click References.
Select Add database reference….
Select System database.
Ensure master is selected.
Press OK.
Note that it might take a while for VS to update.
(Note this was copied verbatim from the stack overflow question with my screenshots added: https://stackoverflow.com/questions/18096029/unresolved-reference-to-obj… - I will explain more if you get past the tldr but it is quite exciting! )
NOT TLDR:
I like this question on stack overflow as it has a common issue that anyone who has a database project that they import into SSDT has faced. It might not affect everyone, but a high percentage of databases will have some piece of code that references something that doesn't exist.
The question has a few little gems in it that I would like to explore in a little more detail because I don't feel that a comment on stack overflow really does them justice.
If we look at the question it starts like this:
If you're doing this from within Visual Studio, make sure that the file is set to "Build" within the properties.
I've had this numerous times and it really gets me everytime. SQL Build is case sensitive even though your collation isn't. Check the case is correct in agreement with the object and schema names that are referenced!

Rename foreign key system name in SQL Server Management Studio is failing

The method or operation is not
permitted.
I assume this is a permission's issue, but I can't figure out where I would change it. It is strange because I can rename an index with no issue.
EDIT:
If you're looking at a table, and you see "Columns, Keys, Constraints, etc.", this is under Keys, and it is the system name that I presume SQL is using to identify the foreign key name I gave the column.
What is the exact error you are getting?
Also, generate a script for your change and paste that script into a query window and try it there. See what the error is. Note that SSMS GUI stuff is NOT the best place to do stuff like this.