Database protected from edit? - sql

If I see this at the bottom of SQL Server Management Studio, does this mean that I do not have permissions to edit a row?

Or the column is a computed column, or populated by the IDENTITY property, or ROWVERSION, or ...
Try and edit the data in this table, you will see that all three columns are read only:
USE tempdb;
GO
CREATE TABLE dbo.flub
(
i INT IDENTITY(1,1),
x AS (i + 1),
r ROWVERSION
);
INSERT dbo.flub DEFAULT VALUES;
If you share the definition of the table, we can at least tell you why if it's because of one of these reasons (we'd need more info to confirm if it's a column-level permissions issue).
Better suggestion: stop using "Open Table", "Edit Top 200 rows" or any other Excel-looking grid to modify data. Write proper DML using UPDATE statements - I promise you the error messages you get when you try to modify a value that you can't will be much more descriptive in almost every case. Examples from above:
UPDATE dbo.flub SET i = 5;
Msg 8102, Level 16, State 1, Line 1
Cannot update identity column 'i'.
UPDATE dbo.flub SET x = 5;
Msg 271, Level 16, State 1, Line 1
The column "x" cannot be modified because it is either a computed column or is the result of a UNION operator.
UPDATE dbo.flub SET r = 0x00;
Msg 272, Level 16, State 1, Line 1
Cannot update a timestamp column.
I talk about several bugs in these UIs here, and others have been reported since. This one, for example, was just fixed in the 2012 version...

If that column you are currently trying to edit is an IDENTITY column, it will display this message.

If you're only getting that message on one or more columns in the table, it sounds like that cell may be a computed column, which by definition does not support updates. Or, it may be an identity column which also does not support updates.
To see if it's a computed column: If you go to the table designer, you will notice no data type specified and instead (in the properties below) a Computed Column Specification. Or, in the DDL you will see an AS clause for the column.

Related

Ambiguous column name on update of new column used in view

Scenario
Adding a column to a table and then updating that column
alter sometable add example_column_name varchar(255);
update sometable set example_column_name = '';
(real update is a bit more complex, but this is a boiled down version we used trying to find the problem)
Problem
The update query gives 'Ambiguous column name example_column_name.'
This works in all databases except one.
It is only for exactly one specific column name it happens, adding a column with different name and updating that column works
The column name in question works in other databases, and it already exists in other tables in the same db
Question
Does anyone know what's going on, how can we get past this problem?
Update
The problem was an indexed view that used the column name of the new column in an already existing query. See comments and accepted answer for details.
This error can't happen purely from the code shown.
There must be a trigger or indexed view in play. You have ruled out triggers so an example demonstrating the indexed view scenario is below
CREATE TABLE T1(X INT, Y INT)
CREATE TABLE T2(X INT, Z INT)
GO
CREATE VIEW V1
WITH SCHEMABINDING
AS
SELECT T1.X,
T1.Y,
Z
FROM dbo.T1
JOIN dbo.T2
ON T1.X = T2.X
GO
CREATE UNIQUE CLUSTERED INDEX IX
ON V1(X)
GO
ALTER TABLE T1
ADD Z INT;
GO
UPDATE T1
SET Z = 0
When the view is initially created the only table containing a column Z is T2 so it is not ambiguous. After adding column Z to T1 the view definition becomes ambiguous. The UPDATE to the table tries to automatically maintain the view and the error is thrown.
Msg 209, Level 16, State 1, Procedure V1, Line 5 [Batch Start Line 23]
Ambiguous column name 'Z'. Msg 4413, Level 16, State 1, Line 25 Could
not use view or function 'V1' because of binding errors.
It is best practice to always use two part naming where your query references more than one table to avoid this type of error.

SQL Server invalid object name insert

Recently I realized I should have a primary key in this table, so I tried to add one by doing the following steps:
Added a new column with nullable values
Filled all the values with integers indexed from 1 - 178
Made the column not allow nulls - this saved fine with no warnings that there
were still null values
I set the identity column to Id (new column I created)
Tried to insert a new row and got the following message
Msg 208, Level 16, State 74, Procedure tr_dbo_SaveState_7d7e8c09-470a-4510-ac78-12bf952f3a14_Sender, Line 63 [Batch Start Line 0]
Invalid object name 'dbo_SaveState_7d7e8c09-470a-4510-ac78-12bf952f3a14/StartMessage/Insert'.
I thought maybe I had to set the identity seed to the lastvalue+1 but still got the same message. I can insert into other tables just fine, and when I put the wrong number of arguments into the VALUES() function I get a different (expected) error, but when doing what I do for other tables, and used to do for this table I now get the above error. Does it seem the insert function is missing for this table? BTW this user has all permissions so that shouldn't be an issue
I also tried undoing this but it seems like the INSERT method for this table has just been deleted, or is somehow unavailable.
I can still select from the table just fine
When I try to update values I don't get the error message if the WHERE clause always results to false, but if there is a row that it tries to update I get an error message - this is not the case when I right-click on the table and Edit top 200 rows, only when I try and do it through query

How do I change a column data type from varchar(255) to date?

I am using a reporting database which consists of 20 tables on SQL Server. In marketing table I have a column report_date which is currently a varchar(255). It is basically a date formatted in a way 2017-12-12. I want to change the type of this column to a date. I’m running this script but getting errors. The script is down below:
USE [reporting].[dbo].[marketing]
GO
SELECT CONVERT(date, 'report_date');
These are the errors I’m getting.
Msg 911, Level 16, State 1, Line 1
Database 'dbo' does not exist. Make sure that the name is entered correctly.
Msg 241, Level 16, State 1, Line 3
Conversion failed when converting date and/or time from character string.
How should I adjust the script?
If you want to change the column's data type (and you should) then you need to use an alter table statement. Your first error message is because of the USE directive - it should be
USE [reporting]
GO
Your second error message is because 'report_date' is a string constant, not a column name.
The select statement should be
SELECT CAST(report_date as date) -- Don't use Convert without the style argument....
FROM [dbo].[marketing]
Note that if you have even a single value that can't be converted to date you will get the second error again.
Basically I would recommend first making sure that the select statement completes without any exceptions, and only then alter the table:
USE reporting
GO
ALTER TABLE [dbo].[marketing]
ALTER COLUMN report_date DATE
GO
TRY THIS:
SELECT CONVERT(DATE, report_date) --If only for comparison
ALTER TABLE marketing ALTER COLUMN report_date DATE --If want to change in the table
The proper way to do this is like;
ALTER TABLE reportin.dbo.marketing ALTER COLUMN 'report_date' date
And you can check this How do you change the datatype of a column in MS SQL?
"Convert" is used for conversion from one datatype to other in select queries, you need to use alter statement for altering database columns and also
USE [databasename] is enough, so rewriting your query here :
USE [reporting]
GO
ALTER TABLE marketing ALTER COLUMN ReportDate DATE
Slow, but safe way is to:
Create a new column (ALTER TABLE dbo.MyTable ADD MyNewColumn DATE NULL;)
Update the new column using the old one (UPDATE dbo.MyTable SET MyNewColumn = CONVERT(DATE, MyColumn);)
Drop the old column (ALTER TABLE dbo.MyTable DROP MyColumn;) - Alternatively, you can rename this column instead and keep it as is)
Rename the new column (EXEC sp_rename 'dbo.MyTable.MyNewColumn', 'MyColumn', 'COLUMN';)
You might have to drop indexes beforehand, but this method (and it's alterations) help to prevent data loss.
If you encounter an error during casting, you should eliminate those values from the update (by for example adding a WHERE clause) and investigate them manually.
If you are using SQL Server 2012 or newer, you can use TRY_CONVERT() to ignore the values which cannot be converted to DATE. In this case you will have NULL in your new column.
Before you do anything, make sure, that all applications and code which is working with this column can handle the changes.
Notes
You might want to rebuild the table/indexes after a change like this.

Invalid Column Name when Inserting Data

I have a local installation of SQLExpress, and accessing it using SQL Server Management Studio.
I created a new database BirdSite in SSMS, with a single table TMasterCountry, with these columns:
Id (int)
CountryName (varchar(50))
where Id is the primary, auto-incrementing key.
When I use the Script table as... option in the object explorer, I am able to view the empty table with this bit of SQL:
USE [BirdSite]
GO
SELECT [Id]
,[CountryName]
FROM [dbo].[TMasterCountry]
GO
without any issues.
However, using the same option to try inserting some data, brings up this SQL:
USE [BirdSite]
GO
INSERT INTO [dbo].[TMasterCountry]
([CountryName])
VALUES
(<CountryName, varchar(50),>)
GO
So I changed the line under VALUES to
(CountryName, 'test')
But when I try running the code, I get these errors:
Msg 207, Level 16, State 1, Line 4
Invalid column name 'CountryName'.
Msg 110, Level 15, State 1, Line 4
There are fewer columns in the INSERT statement than values specified in the VALUES clause. The number of values in the VALUES clause must match the number of columns specified in the INSERT statement.
Does anyone know what might be going on here? The column clearly does exist, as I can SELECT the data just fine.
Following some similar questions on SO, I have tried restarting SSMS and also tried refreshing the local Intellisense cache, but with no luck. I also tried surrounding CountryName in square brackets but with the same result.
Change it to:
USE [BirdSite]
GO
INSERT INTO [dbo].[TMasterCountry]
([CountryName])
VALUES
('test')
GO
<CountryName, varchar(50),> refers to name of column and it's datatype.
Syntax error; Should be
INSERT INTO [dbo].[TMasterCountry]
([CountryName])
VALUES
('test')
You need to replace the entire content between < and > with the value:
INSERT INTO [dbo].[TMasterCountry]
([CountryName])
VALUES
('test')

SQL simplist way to update an INT identity column

I have a column called fixedID, and it's current Value = 2, I want to update this value to be 42. What is the best way to do this. I would like to do this modification as simply as possible. However, if I could do this while doing an select insert that would be fantastic also.
update tblFixedId
set FixedId = (FixedId + 400)
possible to change the value here?
Select * INTO mynewTable from myOldertable
Identity columns are not updatable in SQL Server.
The only way of doing this as an actual UPDATE rather than a DELETE ... INSERT would be to use ALTER TABLE ... SWITCH to mark the column as no longer an IDENTITY column, do the UPDATE then ALTER TABLE ... SWITCH again to re-mark the column as IDENTITY (For example code the first way round see the workarounds on this Connect Item and for the second way here).
Note that in the common scenario that the identity column is the clustered index key the Update will likely be implemented as an INSERT ... DELETE anyway.