I have a Database DB with a table name population but with no Primary Key. Means it can have duplication of data. For example: I have 5 families (f1,f2,f3,f4,f5) with different members inside it (and members may have same name). So I can have exactly same type of record in more than 1 row. Now I want to edit just 1 member of the family, but it is editing all the duplicate records. What I want to do is, I just want to Update my Database once and only once. In other words, I want to use UPDATE command to execute just once. How to do it?
I am using Sql Server Express, VS2010, C# 4.0 (if this info matters).
I am pretty sure my problem may sound stupid to some people (probably many). But it is just a dummy of my problem. Any help or suggestion will be greatly appreciated. Thanks
I know it's not exactly what you're asking but seriously, the easiest option is to alter the database to have a primary key and use that. Perhaps an Identity key....
Without that, you could update just one record, but you have no guarantee of which record. This is why primary keys are such as fundamental concept. I suppose this doesn't really matter if they are all the same, so....
If you really want to proceed without a primary key, you need to use the TOP keyword as shown here: How do I update n rows in a table?
Set it to
UPDATE TOP 1 ....
Add an identity column, ID int with auto increment on. Then update using the id's.
CREATE TABLE dbo.Family
(
Id int NOT NULL IDENTITY (1, 1),
FamilyName varchar(50) NULL
)
update dbo.Family set FamilyName = 'xxx' where Id = y
In case you can't add an identity column for some reason:
UPDATE TOP ( 1 ) Families
SET Whatever = 'Your Value', ...
WHERE <Your where clause>
The real answer is: Fix your database design. Every record should have some unique identifier. Add an auto-increment field or something.
To directly answer your question, you can say "update top (1) ..." to only update one record. But without some unique identifier, how do you know which record to update? The program will essentially update a random record. Which takes me back to point 1.
Edit: Whoops, my original answer was for a different engine. Corrected above.
Related
I have a SQL table user. It has 3 columns id(set as primary and Is Identity as Yes), name and password. When I enter data to the table the id became incremented. But on delete query only name and password will be deleted. I need to delete a particular row including the id.
For example:
id:1 name:abc password:123
id:2 name:wer password:234
id:3 name:lkj password:222
id:4 name:new password:999
I need to delete the third column ie, id:3 name:lkj password:222 . But after deleting this row, the table should be shown as below.
id:1 name:abc password:123
id:2 name:wer password:234
id:3 name:new password:999
From the additional information you have provided it shows you do not understand the IDENTITY data type. As others, including myself, have said numbers are not re-used.
You should also avoid changing primary keys just because a row was deleted.
It would seem you need a row number, don't use the key for this. Create a view using the ROW_NUMBER function, something like
SELECT ROW_NUMBER() OVER (Order by id) AS row_number, name, password, ...
FROM [Your_Table]
As #Tony said, once a number has been used, it isn't available anymore. A workaround for this problem is the following:
1. Don't use an Identity field at all. Use just an integer field set as primary key.
2. Declare a trigger which is triggered whenever a new row is inserted.
3. This trigger has to read the the ID of the last inserted row in the table and increment it by one and insert the result in the ID field.
So when you delete this row later, the ID is available again.
If you want to reuse the id later, that is an extremely poor idea. Don;t go down that path. The only ways to do that are either performance problems or are very subject to error when you have race conditions. There is a reason why udntities don't reuse values after all. The id should be meaningless anyway. There is usually no reason why it can't skip values except personal preference. But personal preference should not take precendence over performance and reliability. If you want to dothis because you hate the skipped values then don't. If you are getting this requirement from above, then push back. Tell them that the alternative are more time-consuming and less reliable and far more likely to cause data integrity problems.
I know getting the id of a record from a db table in CakePHP is easy. I want to get the "future" id of a "future" record of a table, that is, I'll insert a record, but before inserting, I want to get its id, which will be generated by db after insertion is completed(the id is int, Auto Increment). Thanks.
Even the database itself doesn't know what ID it's going to use until the very moment after the record is saved.
You can't (in a multi-user system) ask in advance what the ID is going to be because 20 other records may have been inserted between the time you ask what the ID is going to be, and when you insert your record (with an ID that was used 20 records ago.) This is called a 'Race Condition'.
Here's what will happen:
You: DB - what's the next ID please?
DB: (Does a max() on the column) 21!
You: Great! I'll use that!
(meanwhile 20 other records get inserted by other users)
You: Hi DB, I'd like to insert this record using ID 21 like you told me!
DB: Oops - sorry - that ID has already been used :'-(
You don't NEED to know the record in advance. If you structure your save data correctly, and use CakePHP's saveAccociated() method, CakePHP will insert the correct ID as the foreign key value for all your related data.
The only way to have a predictable ID is to create it yourself. Remember - it MUST be non-null and unique (the definition of a primary key).
Save yourself many, many future primary key clashes and stick to the cake method :-)
One option is you can get the current max id from mysql and then just increment the value. If you have alot of operations going on this might cause some trouble with your site. But you could use:
$this->Model->query("SELECT MAX(id) as max FROM `your_table_name`");
This would get you the max id of that table currently then you can do a +1
Another option would be to get the ID after you save, then update your record with that ID. For example cakephp has a method for this.
$this->Model->getLastInsertID();
$this->Model->updateAll($fields, $conditions)
Reference updateAll: http://book.cakephp.org/2.0/en/models/saving-your-data.html#model-updateall-array-fields-array-conditions
So here's my situation.
I have a table in my database, it has multiple entries, but I need only one to be deleted.
When trying to google this, all I could find was questions referring to deleting all except one of these entries, while I need to delete ONLY ONE and leave the rest.
I'm completely confused on this, and don't really understand how to do it.
You need to use a where clause to identify the row that you want to delete, preferably by the primary key of the table. For example:
delete from MyTable where id = 1
If you post your table's schema, we can help with better syntax.
The row you are trying to delete should have a unique way to identify it, typically the primary key. You would then use the WHERE clause to specify your query to DELETE it:
DELETE FROM sparkles WHERE primaryKey = 1
Alternatively, if there are no keys, you would filter by criteria that matches all values of the record you wish to delete.
DELETE FROM sparkles WHERE col1 = 5 AND col2 = 15 AND col3 = 51
If you are trying to achieve this in Java, you would most probably be using JDBC however if this is just a onetime effort you can directly run the delete query with appropriate where clause.
Well I don't see how this is tagged as Java. But it sounds like you want to use limit operator, like this:
DELETE FROM somedatabase WHERE someentry = 5 LIMIT 1;
The response two above me is good to but leaves out LIMIT.
Step by step for doing it in phpMyAdmin....
Go to phpMyAdmin interface
Select the database
Select the table
Click Browse
Look for the row you are looking to delete and click the delete Icon
Confirm deletion of that row
Done.
If you have 5 Fields in table and you want to delete only one field for particular instance then you should fire update query giving the null effect to that filed...
Suppose If table is
Id | Name | MobNum
And you want to delete MobNum of record 5 ...then query can be ike this>>>
update tlbName set MobNum=null where Id='5'
I am working on social networking site. now our team decide to store user profile in denormalized manner. so our table structure is like this
here attribute it means one fields for user profile e.g. Firstname,LastName,BirthDate etc...
and groups means name of a group of fields e.g. Personal Details, Academic Info, Achievements etc..
**
Attribute/Groups master - it creates
hierarchy of groups and attributes.
**
Attribute_GroupId bigint
ParentId bigint
Attribute_GroupName nvarchar(1000)
ISAttribute bit
DisplayName nvarchar(1000)
DisplaySequence int
**
Attribute Control Info - stores which
control have to be populated at run
time for the attribute as well as its
validation criteria...
**
Attribute_ControlInfoId bigint
AttributeId bigint
ControlType nvarchar(1000)
DataType nvarchar(1000)
DefaultValue nvarchar(1000)
IsRequired bit
RegulareExpression nvarchar(1000)
**
And finally Attribute Values where for
every attribute , user wise values
will be stored
**
AttributeId bigint Checked
IsValueOrRefId bit Checked
Value nvarchar(MAX) Checked
ReferenceDataId bigint Checked
UserId bigint Checked
Unchecked
Now they are saying that we'll create index on Attribute Values table. there is no primary key also there.
AS there's huge data going to be stored in this table. e.g. if there are 50 million users and 30 attributes are there it'll store 1500 million records. in this case if we create index on table, isn't Insert and Update statement will be very slow as well as at time of data fetching for one user. quires will also be very slow.
i thought one option for that like instead of attribute wise values i can store one XML record for one user.
so, please can anybody help me out to find out best option for this case. how should i store data?
here i can not make hard code table because at any time new fields can be added by administrator so i need some data structure where i can easily add any fields in user profile with 1-2 steps only.
please reply me if anybody has better solution for this.
You guys need a dba!
This is one of those EAV tables that is going to bite you down the road!
Bill Karwin (his blog) put together a SQL Anti-patterns PPT
Link 1
Link 2
He offers 3 alternate solution to EAV.
Indexing is the least of your worries...
Check out those articles which highlight just how bad that design choice is, and what potential problems you're getting yourself into if you stick to that design:
Five Simple Database Design Errors You Should Avoid
Joe Celko: Avoiding the EAV of Destruction
Bad CaRMa
It seems to be a fairly common design problem - and it seems like a good idea to programmers to solve it that way, with a attribute/value table - but it's really not a good idea from a database performance point of view.
Also:
Now they are saying that we'll create
index on Attribute Values table. there
is no primary key also there.
As some SQL gurus like to say: "If it doesn't have a primary key, it's not a table".
You definitely need to find a way to get a primary key onto your tables - if you don't have anything that you can use per se, add a column "ID" of type "INT IDENTITY(1,1)" to it and put the primary key on that column. You need a primary key! Database design, first lesson, first five minutes....
You need to rethink your design and come up with something more clever to store the data you need.
I have an Orders table which has a Quantity column. During check in or check out, we need to update that Quantity column by one. Is there a way to do this in one action or we have to get the existing value and then add or minus one on top of it?
Another question is when we insert a new row, do we need to check if same data existing then insert if not, which is two steps, or is there a better way to do this?
thanks,
To answer the first:
UPDATE Orders SET Quantity = Quantity + 1 WHERE ...
To answer the second:
There are several ways to do this. Since you did not specify a database, I will assume MySQL.
INSERT INTO table SET x=1, y=2 ON DUPLICATE KEY UPDATE x=x+1, y=y+2
REPLACE INTO table SET x=1, y=2
They both can handle your question. However, the first syntax allows for more flexibility to update the record rather than just replace it (as the second one does).
Keep in mind that for both to exist, there has to be a UNIQUE key defined...
The single-step answer to the first question is to use something like:
update TBL set CLM = CLM + 1 where key = 'KEY'
That's very much a single-instruction way of doing it.
As for the second question, you shouldn't need to resort to DBMS-specific SQL gymnastics (like UPSERT) to get the result you want. There's a standard method to do update-or-insert that doesn't require a specific DBMS.
try:
insert into TBL (key,val) values ('xyz',0)
catch:
do nothing
update TBL set val = val + 1 where key = 'xyz'
That is, you try to do the creation first. If it's already there, ignore the error. Otherwise you create it with a 0 value.
Then do the update which will work correctly whether or not:
the row originally existed.
someone updated it between your insert and update.
It's not a single instruction and yet, surprisingly enough, it's how we've been doing it successfully for a long long time.
UPDATE Orders Order
SET Order.Quantity = Order.Quantity - 1
WHERE SomeCondition(Order)
As far as I know there is no build-in support for INSERT-OR-UPDATE in SQL. I suggest to create a stored procedure or use a conditional query to achiev this. Here you can find a collection of solutions for different databases.
If my understanding is correct, updates should be pretty simple. I would just do the following.
UPDATE TABLE SET QUANTITY = QUANTITY + 1 and
UPDATE TABLE SET QUANTITY = QUANTITY - 1 where QUANTITY > 0
You may need additional filters to just update a single row instead of all the rows.
For inserts, you can cache some unique id related to your record locally and check against this cache and decide whether to insert or not. The alternative approach is to always insert and check for PK violation error and ignore since this is a redundant insert.
to answer the second:
make the column unique and catch the exception if it's set to the same value.
#dotjoe
It is cheaper to update and check ##rowcount, do an insert after then fact.
Exceptions are expensive && updates are more frequent
Suggestion: If you want to be uber performant in your DAL, make the front end pass in a unique ID for the row to be updated, if null insert.
The DALs should be CRUD, and not need to worry about being stateless.
If you make it stateless, With good indexes, you will not see a diff with the following SQL vs 1 statement.
IF (select top 1 * form x where PK=#ID)
Insert
else
update