How to determine a table's dependencies? - sql-server

I need to migrate some data between environments. The data structures are going to be exactly the same, however some of the data is ID dependent on existing data which will have to be adapted, or more precisely, userIds (such as ownership, last modification, etc).
I have already established as a requirement that usernames on both environments will always refer to the same user, so what I need to do is to determine which columns reference the user table, and transform my data from one environment to the other.
I have tried checking the SQL Server Management Studio's Object dependencies on the user table, and got a detailed list of which objects are referencing the ID column. However, there is at least one table that i know that does refer the ID column that does not appear in the list.
Constraint Options on Table
Dependants on the user table
Attempting to update a row from the proposal table with an unexisting id displays the expected exception:
Msg 547, Level 16, State 0, Line 1
The UPDATE statement conflicted with the FOREIGN KEY constraint "OSFRK_OSUSR_tpt_PROPOSAL_OSUSR_A7L_USER_MASTER_CREATEDBY". The conflict occurred in database "databasename", table "dbo.OSUSR_A7L_USER_MASTER", column 'ID'.
Can there be any reason for this table to not appear as a dependent on the user's table? Is there a way to determine if there are more tables that are not being displayed?

Try this may be it will helpful for you.
EXEC sp_fkeys 'TableName'

You can follow the following procedure, in Object Explorer, expand Databases, expand a database, and then expand Tables.
Right-click a table, and then click View Dependencies.
In the Object Dependencies dialog box, select either Objects that depend on , or Objects on whichdepends.
Select an object in the Dependencies grid. The type of object (such as "Trigger" or "Stored Procedure"), appears in the Type box.
Also, this link is very helpful: https://learn.microsoft.com/en-us/sql/relational-databases/tables/view-the-dependencies-of-a-table?view=sql-server-2017

You can use also this command:
USE [databasename]
GO
EXEC sp_depends #objname = 'objectname';

Related

Common TVF in SQL Server to get results from different schema

I have been using SQL Server for the past month and I need a suggestion from SQL Server folks to help me on this use case.
The tables below are just to explain about the idea that I am looking for.
I have tables in different schema like this:
MyDb.dbo.Festivals
MyDb.India.Festivals
MyDb.China.Festivals
MyDb.USA.Festivals
I am writing a table value function without any schema prefixed in it like
CREATE FUNCTION getFestivals()
RETURNS TABLE
AS
RETURN
(SELECT * FROM festivals)
As I haven't applied any schema, it defaults to dbo and creates the TVF as dbo.getFestivals(). Now I have created synonyms for all other schemas
CREATE SYNONYM India.getFestivals FOR dbo.getFestivals;
CREATE SYNONYM USA.getFestivals FOR dbo.getFestivals;
I tried to query like
SELECT *
FROM MyDb.India.getFestivals()
and it returns the festivals from dbo.festivals and not india.festivals.
I understand that though the synonyms, we've created it just executes the select query in the dbo schema context and not in india schema context.
I want suggestions on how to have a common table value function that will query based on the schema prefixed, i.e. MyDB.India.getFestivals() should get festivals from India and MyDB.USA.getFestivals() should return festivals from USA.
Question
Is there a way I can have a table value function that can query based on the schema context.
the only possible way I can think of is to create the same TableValue function in all schemas
Caveats
I have to stick to table value function only and the above use case is a sample scenario to explain my problem
I understand that though the synonyms, we've created it just executes
the select query in the dbo schema context and not in india schema
context.
You should always schema qualify objects in your queries, since you did not do it, SQL Server first looks for festivals in the same schema where the procedure resides, if it's not found then dbo schema is checked, if it's not found even in dbo, the error is raised.
In your case procedure resides in dbo schema so only dbo schema is checked in order to find festivals.
It may be wrong design if many "similar" tables are created instead of one table, can you merge them all into one table adding country_id to distinguish the country?
If not, can you at least add this field to every table? If it's so, just add the field for the country in every table, add check constraint on this field to reflect the only country that is stored in every table an then use partitioned view in your function.
Partitioned view is a view composed of union all of some tables with the same structure, each of which has check constraint on the same column that defines the values this column is restricted to. When you use this view with the filter on country column, all the tables except for the correct one will be eliminated from execution plan thanks to check constraint defined on this column.
So you can change your function to accept the only parameter that is country and it will read only one table corresponding to parameter passed.
More on partitioned views here: Using Partitioned Views

Cannot insert duplicate key row in object with unique index . The duplicate key value. The statement has been terminated

I am new to Outsystems and SQL. I am try to create a Bus Application where the entities are
When I try to create a new rider with the same name and different Route and bus Id. I get
Cannot insert duplicate key row in object 'dbo.OSUSR_6SL_RIDER' with unique index 'OSIDX_OSUSR_6SL_RIDER_4NAME'. The duplicate key value is (ABC).
The statement has been terminated.
When I check Name field in the database table 'dbo.OSUSR_6SL_RIDER' it is not having the unique identifier set up. Can anybody please help me with this.
Open the Indexes tree under your table. You will find an Index named 'OSIDX_OSUSR_6SL_RIDER_4NAME'.
Script out that Index and you will see that it is a UNIQUE index on a "name" column that you are trying to create a duplicate value in.
You must either change that Index to include Route and Bus ID, or you must abandon your attempt to create a new row with a duplicate name.
It looks like you are are creating an exact duplicate, i.e. a record with the same Id value. The index name it refers to seems to be auto generated by the db system. Therefor it is not necessarily referring to the Name field. Have a look at your indexes and look at the fields they contain. I wouldn't be surprised if OSIDX_OSUSR_6SL_RIDER_4NAME contains the Id field.
If you are using the OutSystems platform, all the database management is done/generated when you publish from Service Studio, so it isn’t advisable to manipulate the database directly: you’re setting yourself up for a lot of maintenance pain and inconsistencies between different environments.
Double-click on the Entity Rider and it’ll open the edit window of your entity. In the Indexes tab you can define and change your indexes (unique or not) and the tool will (re)generate all the needed SQL commands.
See OutSystems Platform 9 Help | Indexes Tab for more details:

SQL Server Replication Action if name is in use questions

When configuring a new Merge Replication, setting properties of all articles, I'm having a problem. In Destination Object -> Action if name is in use, I can select four different options. I'm trying to figure out what is each one. I'm not finding anything about it, they are:
Keep existing object unchanged
Drop existing object and create a new one
Delete data. If article has a row filter, delete only data that matches the filter.
Truncate all data in the existing object
The article property Action if name is in use correlates to the #pre_creation_cmd argument of sp_addmergearticle:
Specifies what the system is to do if the table exists at the
subscriber when applying the snapshot. pre_creation_cmd is
nvarchar(10), and can be one of the following values.
none - If the table already exists at the Subscriber, no action is taken.
delete - Issues a delete based on the WHERE clause in the subset filter.
drop (default) - Drops the table before re-creating it. Required to support Microsoft SQL Server Compact Subscribers.
truncate - Truncates the destination table.

Why i cant add new columns to my Users table?

I am doing some homework. The users of my database uses some other attributes, not just the ones that ASP 2.0 automatically created for me when i implemented the login and registration mechanism. But when i try to save the modification displays me an error. Can someone give me a hand?
This is the error:
The error says:
'aspnet_Users' table
- Unable to modify table. ALTER TABLE only allows columns to be added
that can contain nulls, or have a
DEFAULT definition specified, or the
column being added is an identity or
timestamp column, or alternatively if
none of the previous conditions are
satisfied the table must be empty to
allow addition of this column. Column
'kjoptekvoten' cannot be added to
non-empty table 'aspnet_Users' because
it does not satisfy these conditions.
That database was automatically created when i implemented Forms based authentification and registration. The problem now is that that users needs some more attributes. How can i give to it more attributes? What is the easiest way to do it?Does not mind if it is not theorically correct(It is just for a homework).
I would appreciate a lot your help.
Apart form the technicalities on the database side, there is a deeper issue here.
You should not alter the aspnet_Users table because you are bypassing the way the membership 'system' in asp.net is working. Instead, have a look into the Profile mechanism: https://web.archive.org/web/20211020111657/https://www.4guysfromrolla.com/articles/101106-1.aspx
You need to make the new attributes nullable or provide a default value. But you also need to consider how to obtain the values from db. The sql membership provider utilizes an auto generated stored procedure to put data into the membership user instance returned,so just adding the attributes in the table will not be sufficient to get the attribute values to your application. I would use a user attribute table instead.
The error message says it all:
You are adding a new column that can't be Null (checkbox "Allow Nulls" not checked), but as you didn't provide a default value, it will be Null.
So SQL Server can't create the new column.
You can do two things:
a) Create the new column with Nulls allowed.
THEN put a default value in all existing rows:
update aspnet_Users set kjoptekvoten = 0)
...and THEN uncheck "Allow Nulls"
b) Create the new column directly with default values.
I don't know if you can do this in Management Studio, but it's easy in T-SQL:
alter table aspnet_Users
add kjoptekvoten int not null
constraint Name_For_Constraint default(0) with values
This will add the new not nullable column, AND create a constraint with a default value, AND fill the default value in all existing rows (SQL Server will not do this without the "with values" clause).
Normally I just set the column as allow nulls
then do an SQL UPDATE TABLE SET VALUE = whateva
then update the table definition to not allow nulls.

Updateable view in mssql with multiple tables and computed values

Huge database in mssql2005 with big codebase depending on the structure of this database.
I have about 10 similar tables they all contain either the file name or the full path to the file. The full path is always dependent on the item id so it doesn't make sense to store it in the database. Getting useful data out of these tables goes a little like this:
SELECT a.item_id
, a.filename
FROM (
SELECT id_item AS item_id
, path AS filename
FROM xMedia
UNION ALL
-- media_path has a different collation
SELECT item_id AS item_id
, (media_path COLLATE SQL_Latin1_General_CP1_CI_AS) AS filename
FROM yMedia
UNION ALL
-- fullPath contains more than just the filename
SELECT itemId AS item_id
, RIGHT(fullPath, CHARINDEX('/', REVERSE(fullPath))-1) AS filename
FROM zMedia
-- real database has over 10 of these tables
) a
I'd like to create a single view of all these tables so that new code using this data-disaster doesn't need to know about all the different media tables. I'd also like use this view for insert and update statements. Obviously old code would still rely on the tables to be up to date.
After reading the msdn page about creating views in mssql2005 I don't think a view with SCHEMABINDING would be enough.
How would I create such an updateable view?
Is this the right way to go?
Scroll down on the page you linked and you'll see a paragraph about updatable views. You can not update a view based on unions, amongst other limitations. The logic behind this is probably simple, how should Sql Server decide on what source table/view should receive the update/insert?
You can modify partitioned views, provided they satisfy certain conditions.
These conditions include having a partitioning column as a part of the primary key on each table, and having a set on non-overlapping check constraints for the partitioning column.
This seems to be not your case.
In your case, you may do either of the following:
Recreate you tables as views (with computed columns) for your legacy soft to work, and refer to the whole table from the new soft
Use INSTEAD OF triggers to update the tables.
If a view is based on multiple base tables, UPDATE statement on the view may or may not work depending on the UPDATE statement. If the UPDATE statement affects multiple base tables, SQL server throws an error. Whereas, if the UPDATE affects only one base table in the view then the UPDATE will work (Not correctly always). The insert and delete statements will always fail.
INSTEAD OF Triggers, are used to correctly UPDATE, INSERT and DELETE from a view that is based on multiple base tables. The following links has examples along with a video tutorial on the same.
INSTEAD OF INSERT Trigger
INSTEAD OF UPDATE Trigger
INSTEAD OF DELETE Trigger

Resources