According to this:
Microsoft description of how SQL works
This problem occurs when you make one or more of the following changes
to the table: You change the Allow Nulls setting for a column. You
reorder columns in the table. You change the column data type. You add
a new column. You change the filegroup of a table or its text/image
data.
I tried changing the max length of a nvchar from 25 to 100 on a column and it won't let me save it.
It is not at all listed as being one of the conditions under which this error should be presented.
Can anyone tell me why SSMS 18 is doing this to me?
Check for dependencies (i.e. Foreign Keys)
Use ALTER, for example
CREATE TABLE [dbo].[Test]( [aaa] nchar NULL) ON [PRIMARY] GO
ALTER TABLE Test ALTER COLUMN aaa NCHAR(100)
SSMS is quite quirky when it comes to database objects.
The article you linked to explains what the issue is.
SSMS has a safeguard built in that prevents you saving changing where its script would drop and re-create the table.
Sometimes SSMS can be overly cautious and it's not even necessary.
You can (and probably should) use the alter table syntax directly, however you can disable this behaviour in SSMS by going to:
tools > options > Designers > Table and Database Desingners
and then untick the option Prevent saving changes that require table re-creation
How can I create a Trigger that delete a column only if all values on a specific field are null?
What do you mean "create a trigger"? Do you mean that you want an update/delete trigger that would delete the column at the point when all the values become NULL?
If so, that is not possible. "Deleting a column" is really alter table drop column. In the Remarks section for the create trigger documentation:
Additionally, the following Transact-SQL statements are not allowed
inside the body of a DML trigger when it is used against the table or
view that is the target of the triggering action . . .
ALTER TABLE when used to do the following: Add, modify, or drop columns. Switch partitions. Add or drop PRIMARY KEY or UNIQUE
constraints.
Hence what you want to do is not possible. Further, I don't understand why you would want to do it. A data-driven change to the data structure seems strange. I am guessing that your data structure really wants to be a junction/association table, but you don't provide enough information to speculate further.
Normaly i would do a delete * from XXX but on this table thats very slow, it normaly has about 500k to 1m rows in it ( one is a varbinary(MAX) if that mathers ).
Basicly im wondering if there is a quick way to emty the table of all content, its actualy quicker to drop and recreate it then to delete the content via the delete sql statement
The reason i dont want to recreate the table is because its heavly used and delete/recreate i assume will destroy indexs and stats gathered by sql server
Im also hoping there is a way to do this because there is a "clever" way to get row count via sys.sysindexes , so im hoping there is a equaly clever way to delete content
Truncate table is faster than delete * from XXX. Delete is slow because it works one row at a time. There are a few situations where truncate doesn't work, which you can read about on MSDN.
As other have said, TRUNCATE TABLE is far quicker, but it does have some restrictions (taken from here):
You cannot use TRUNCATE TABLE on tables that:
- Are referenced by a FOREIGN KEY constraint. (You can truncate a table that has a foreign key that references itself.)
- Participate in an indexed view.
- Are published by using transactional replication or merge replication.
For tables with one or more of these characteristics, use the DELETE statement instead.
The biggest drawback is that if the table you are trying to empty has foreign keys pointing to it, then the truncate call will fail.
You can rename the table in question, create a table with an identical schema, and then drop the original table at your leisure.
See the MySQL 5.1 Reference Manual for the [RENAME TABLE][1] and [CREATE TABLE][2] commands.
RENAME TABLE tbl TO tbl_old;
CREATE TABLE tbl LIKE tbl_old;
DROP TABLE tbl_old; -- at your leisure
This approach can help minimize application downtime.
I would suggest using TRUNCATE TABLE, it's quicker and uses less resources than DELETE FROM xxx
Here's the related MSDN article
Truncate table in MS Sql Server
Truncate table in Mysql
all the procedure help I find is used for select purposes only.
can I write a table to truncate several tables?
similar to (but this does NOT work)
CREATE PROCEDURE clearall()
BEGIN
truncate tallgrrl.auth;
truncate tallgrrl.factory;
truncate tallgrrl.farm;
truncate tallgrrl.player;
truncate tallgrrl.timer;
END;
Absolutely. One of the purposes of stored procedures is to encapsulate logic/multiple operations.
truncate might not work if you have relationships with that table in that case you need to either
use delete
drop the relationship truncate the table and recreate the relationship again
I don't know why your TRUNCATE isn't working. I have stored procs that TRUNCATE tables. What DB platform are you using?
Does your TRUNCATE work outside of the SP? As SQLMenace mentions, you cannot use TRUNCATE on tables with FK dependencies.
Try switching to "delete from [table name]", because truncate might not work due to rights issue.
You should be able to. Perhaps you are doing your truncations in the wrong order (and violating the integrity constraints. e.g., you can't delete a parent until there are no children hanging off of it.
You may need to change the order of the truncations so that foreign keys are not truncated before the data that references them.
What error(s) do you get?
Besides the aforementioned FK potential issue, depending on the rights of the user executing the proc you might not have permissions to truncate.
I had to delete all the rows from a log table that contained about 5 million rows. My initial try was to issue the following command in query analyzer:
delete from client_log
which took a very long time.
Check out truncate table which is a lot faster.
I discovered the TRUNCATE TABLE in the msdn transact-SQL reference. For all interested here are the remarks:
TRUNCATE TABLE is functionally identical to DELETE statement with no WHERE clause: both remove all rows in the table. But TRUNCATE TABLE is faster and uses fewer system and transaction log resources than DELETE.
The DELETE statement removes rows one at a time and records an entry in the transaction log for each deleted row. TRUNCATE TABLE removes the data by deallocating the data pages used to store the table's data, and only the page deallocations are recorded in the transaction log.
TRUNCATE TABLE removes all rows from a table, but the table structure and its columns, constraints, indexes and so on remain. The counter used by an identity for new rows is reset to the seed for the column. If you want to retain the identity counter, use DELETE instead. If you want to remove table definition and its data, use the DROP TABLE statement.
You cannot use TRUNCATE TABLE on a table referenced by a FOREIGN KEY constraint; instead, use DELETE statement without a WHERE clause. Because TRUNCATE TABLE is not logged, it cannot activate a trigger.
TRUNCATE TABLE may not be used on tables participating in an indexed view.
There is a common myth that TRUNCATE somehow skips transaction log.
This is misunderstanding, and is clearly mentioned in MSDN.
This myth is invoked in several comments here. Let's eradicate it together ;)
For reference TRUNCATE TABLE also works on MySQL
I use the following method to zero out tables, with the added bonus that it leaves me with an archive copy of the table.
CREATE TABLE `new_table` LIKE `table`;
RENAME TABLE `table` TO `old_table`, `new_table` TO `table`;
forget truncate and delete. maintain your table definitions (in case you want to recreate it) and just use drop table.
truncate table client_log
is your best bet, truncate kills all content in the table and indices and resets any seeds you've got too.
truncate table is not SQL-platform independent. If you suspect that you might ever change database providers, you might be wary of using it.
On SQL Server you can use the Truncate Table command which is faster than a regular delete and also uses less resources. It will reset any identity fields back to the seed value as well.
The drawbacks of truncate are that it can't be used on tables that are referenced by foreign keys and it won't fire any triggers. Also you won't be able to rollback the data if anything goes wrong.
Note that TRUNCATE will also reset any auto incrementing keys, if you are using those.
If you do not wish to lose your auto incrementing keys, you can speed up the delete by deleting in sets (e.g., DELETE FROM table WHERE id > 1 AND id < 10000). It will speed it up significantly and in some cases prevent data from being locked up.
Yes, well, deleting 5 million rows is probably going to take a long time. The only potentially faster way I can think of would be to drop the table, and re-create it. That only works, of course, if you want to delete ALL data in the table.
The suggestion of "Drop and recreate the table" is probably not a good one because that goofs up your foreign keys.
You ARE using foreign keys, right?
If you cannot use TRUNCATE TABLE because of foreign keys and/or triggers, you can consider to:
drop all indexes;
do the usual DELETE;
re-create all indexes.
This may speed up DELETE somewhat.
I am revising my earlier statement:
You should understand that by using
TRUNCATE the data will be cleared but
nothing will be logged to the
transaction log. Writing to the log
is why DELETE will take forever on 5
million rows. I use TRUNCATE often
during development, but you should be
wary about using it on a production
database because you will not be able
to roll back your changes. You should
immediately make a full database
backup after doing a TRUNCATE to
establish a new basis for restoration.
The above statement was intended to prompt you to be sure that you understand there is difference between the two. Unfortunately, it is poorly written and makes unsupported statements as I have not actually done any testing myself between the two. It is based on statements that I have heard from others.
From MSDN:
The DELETE statement removes rows one
at a time and records an entry in the
transaction log for each deleted row.
TRUNCATE TABLE removes the data by
deallocating the data pages used to
store the table's data, and only the
page deallocations are recorded in the
transaction log.
I just wanted to say that there is a fundamental difference between the two and because there is a difference, there will be applications where one or the other may be inappropriate.
DELETE * FROM table_name;
Premature optimization may be dangerous. Optimizing may mean doing something weird, but if it works you may want to take advantage of it.
SELECT DbVendor_SuperFastDeleteAllFunction(tablename, BOZO_BIT) FROM dummy;
For speed I think it depends on...
The underlying database: Oracle, Microsoft, MySQL, PostgreSQL, others, custom...
The table, it's content, and related tables:
There may be deletion rules. Is there an existing procedure to delete all content in the table? Can this be optimized for the specific underlying database engine? How much do we care about breaking things / related data? Performing a DELETE may be the 'safest' way assuming that other related tables do not depend on this table. Are there other tables and queries that are related / depend on the data within this table? If we don't care much about this table being around, using DROP might be a fast method, again depending on the underlying database.
DROP TABLE table_name;
How many rows are being deleted? Is there other information that is quickly gleaned that will optimize the deletion? For example, can we tell if the table is already empty? Can we tell if there are hundreds, thousands, millions, billions of rows?