I have this code:
string insertSql =
"INSERT INTO aspnet_GameProfiles(UserId,GameId) VALUES(#UserId, #GameId)";
using (SqlConnection myConnection = new SqlConnection(myConnectionString))
{
myConnection.Open();
SqlCommand myCommand = new SqlCommand(insertSql, myConnection);
myCommand.Parameters.AddWithValue("#UserId", newUserId);
myCommand.Parameters.AddWithValue("#GameId", newGameId);
myCommand.ExecuteNonQuery();
myConnection.Close();
}
When I insert into this table, I have an auto_increment int primary key column called GamesProfileId, how can i get the last inserted one after this so I can use that id to insert into another table?
For SQL Server 2005+, if there is no insert trigger, then change the insert statement (all one line, split for clarity here) to this
INSERT INTO aspnet_GameProfiles(UserId,GameId)
OUTPUT INSERTED.ID
VALUES(#UserId, #GameId)
For SQL Server 2000, or if there is an insert trigger:
INSERT INTO aspnet_GameProfiles(UserId,GameId)
VALUES(#UserId, #GameId);
SELECT SCOPE_IDENTITY()
And then
Int32 newId = (Int32) myCommand.ExecuteScalar();
You can create a SqlCommand with CommandText equal to
INSERT INTO aspnet_GameProfiles(UserId, GameId) OUTPUT INSERTED.ID VALUES(#UserId, #GameId)
and execute int id = (int)command.ExecuteScalar.
This MSDN article will give you some additional techniques.
string insertSql =
"INSERT INTO aspnet_GameProfiles(UserId,GameId) VALUES(#UserId, #GameId)SELECT SCOPE_IDENTITY()";
int primaryKey;
using (SqlConnection myConnection = new SqlConnection(myConnectionString))
{
myConnection.Open();
SqlCommand myCommand = new SqlCommand(insertSql, myConnection);
myCommand.Parameters.AddWithValue("#UserId", newUserId);
myCommand.Parameters.AddWithValue("#GameId", newGameId);
primaryKey = Convert.ToInt32(myCommand.ExecuteScalar());
myConnection.Close();
}
This will work.
I had the same need and found this answer ..
This creates a record in the company table (comp), it the grabs the auto ID created on the company table and drops that into a Staff table (staff) so the 2 tables can be linked, MANY staff to ONE company. It works on my SQL 2008 DB, should work on SQL 2005 and above.
===========================
CREATE PROCEDURE [dbo].[InsertNewCompanyAndStaffDetails]
#comp_name varchar(55) = 'Big Company',
#comp_regno nchar(8) = '12345678',
#comp_email nvarchar(50) = 'no1#home.com',
#recID INT OUTPUT
-- The '#recID' is used to hold the Company auto generated ID number that we are about to grab
AS
Begin
SET NOCOUNT ON
DECLARE #tableVar TABLE (tempID INT)
-- The line above is used to create a tempory table to hold the auto generated ID number for later use. It has only one field 'tempID' and its type INT is the same as the '#recID'.
INSERT INTO comp(comp_name, comp_regno, comp_email)
OUTPUT inserted.comp_id INTO #tableVar
-- The 'OUTPUT inserted.' line above is used to grab data out of any field in the record it is creating right now. This data we want is the ID autonumber. So make sure it says the correct field name for your table, mine is 'comp_id'. This is then dropped into the tempory table we created earlier.
VALUES (#comp_name, #comp_regno, #comp_email)
SET #recID = (SELECT tempID FROM #tableVar)
-- The line above is used to search the tempory table we created earlier where the ID we need is saved. Since there is only one record in this tempory table, and only one field, it will only select the ID number you need and drop it into '#recID'. '#recID' now has the ID number you want and you can use it how you want like i have used it below.
INSERT INTO staff(Staff_comp_id)
VALUES (#recID)
End
-- So there you go. You can actually grab what ever you want in the 'OUTPUT inserted.WhatEverFieldNameYouWant' line and create what fields you want in your tempory table and access it to use how ever you want.
I was looking for something like this for ages, with this detailed break down, I hope this helps.
In pure SQL the main statement kools like:
INSERT INTO [simbs] ([En]) OUTPUT INSERTED.[ID] VALUES ('en')
Square brackets defines the table simbs and then the columns En and ID, round brackets defines the enumeration of columns to be initiated and then the values for the columns, in my case one column and one value. The apostrophes enclose a string
I will explain you my approach:
It might be not easy to understand but i hope useful to get the big picture around using the last inserted id. Of course there are alternative easier approaches. But I have reasons to keep mine. Associated functions are not included, just their names and parameter names.
I use this method for medical artificial intelligence
The method check if the wanted string exist in the central table (1). If the wanted string is not in the central table "simbs", or if duplicates are allowed, the wanted string is added to the central table "simbs" (2). The last inseerted id is used to create associated table (3).
public List<int[]> CreateSymbolByName(string SymbolName, bool AcceptDuplicates)
{
if (! AcceptDuplicates) // check if "AcceptDuplicates" flag is set
{
List<int[]> ExistentSymbols = GetSymbolsByName(SymbolName, 0, 10); // create a list of int arrays with existent records
if (ExistentSymbols.Count > 0) return ExistentSymbols; //(1) return existent records because creation of duplicates is not allowed
}
List<int[]> ResultedSymbols = new List<int[]>(); // prepare a empty list
int[] symbolPosition = { 0, 0, 0, 0 }; // prepare a neutral position for the new symbol
try // If SQL will fail, the code will continue with catch statement
{
//DEFAULT und NULL sind nicht als explizite Identitätswerte zulässig
string commandString = "INSERT INTO [simbs] ([En]) OUTPUT INSERTED.ID VALUES ('" + SymbolName + "') "; // Insert in table "simbs" on column "En" the value stored by variable "SymbolName"
SqlCommand mySqlCommand = new SqlCommand(commandString, SqlServerConnection); // initialize the query environment
SqlDataReader myReader = mySqlCommand.ExecuteReader(); // last inserted ID is recieved as any resultset on the first column of the first row
int LastInsertedId = 0; // this value will be changed if insertion suceede
while (myReader.Read()) // read from resultset
{
if (myReader.GetInt32(0) > -1)
{
int[] symbolID = new int[] { 0, 0, 0, 0 };
LastInsertedId = myReader.GetInt32(0); // (2) GET LAST INSERTED ID
symbolID[0] = LastInsertedId ; // Use of last inserted id
if (symbolID[0] != 0 || symbolID[1] != 0) // if last inserted id succeded
{
ResultedSymbols.Add(symbolID);
}
}
}
myReader.Close();
if (SqlTrace) SQLView.Log(mySqlCommand.CommandText); // Log the text of the command
if (LastInsertedId > 0) // if insertion of the new row in the table was successful
{
string commandString2 = "UPDATE [simbs] SET [IR] = [ID] WHERE [ID] = " + LastInsertedId + " ;"; // update the table by giving to another row the value of the last inserted id
SqlCommand mySqlCommand2 = new SqlCommand(commandString2, SqlServerConnection);
mySqlCommand2.ExecuteNonQuery();
symbolPosition[0] = LastInsertedId; // mark the position of the new inserted symbol
ResultedSymbols.Add(symbolPosition); // add the new record to the results collection
}
}
catch (SqlException retrieveSymbolIndexException) // this is executed only if there were errors in the try block
{
Console.WriteLine("Error: {0}", retrieveSymbolIndexException.ToString()); // user is informed about the error
}
CreateSymbolTable(LastInsertedId); //(3) // Create new table based on the last inserted id
if (MyResultsTrace) SQLView.LogResult(LastInsertedId); // log the action
return ResultedSymbols; // return the list containing this new record
}
I tried the above but they didn't work, i found this thought, that works a just fine for me.
var ContactID = db.GetLastInsertId();
Its less code and i easy to put in.
Hope this helps someone.
You can also use a call to SCOPE_IDENTITY in SQL Server.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
namespace DBDemo2
{
public partial class Form1 : Form
{
string connectionString = "Database=company;Uid=sa;Pwd=mypassword";
System.Data.SqlClient.SqlConnection connection;
System.Data.SqlClient.SqlCommand command;
SqlParameter idparam = new SqlParameter("#eid", SqlDbType.Int, 0);
SqlParameter nameparam = new SqlParameter("#name", SqlDbType.NChar, 20);
SqlParameter addrparam = new SqlParameter("#addr", SqlDbType.NChar, 10);
public Form1()
{
InitializeComponent();
connection = new System.Data.SqlClient.SqlConnection(connectionString);
connection.Open();
command = new System.Data.SqlClient.SqlCommand(null, connection);
command.CommandText = "insert into employee(ename, city) values(#name, #addr);select SCOPE_IDENTITY();";
command.Parameters.Add(nameparam);
command.Parameters.Add(addrparam);
command.Prepare();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void buttonSave_Click(object sender, EventArgs e)
{
try
{
int id = Int32.Parse(textBoxID.Text);
String name = textBoxName.Text;
String address = textBoxAddress.Text;
command.Parameters[0].Value = name;
command.Parameters[1].Value = address;
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
reader.Read();
int nid = Convert.ToInt32(reader[0]);
MessageBox.Show("ID : " + nid);
}
/*int af = command.ExecuteNonQuery();
MessageBox.Show(command.Parameters["ID"].Value.ToString());
*/
}
catch (NullReferenceException ne)
{
MessageBox.Show("Error is : " + ne.StackTrace);
}
catch (Exception ee)
{
MessageBox.Show("Error is : " + ee.StackTrace);
}
}
private void buttonSave_Leave(object sender, EventArgs e)
{
}
private void Form1_Leave(object sender, EventArgs e)
{
connection.Close();
}
}
}
There are all sorts of ways to get the Last Inserted ID but the easiest way I have found is by simply retrieving it from the TableAdapter in the DataSet like so:
<Your DataTable Class> tblData = new <Your DataTable Class>();
<Your Table Adapter Class> tblAdpt = new <Your Table Adapter Class>();
/*** Initialize and update Table Data Here ***/
/*** Make sure to call the EndEdit() method ***/
/*** of any Binding Sources before update ***/
<YourBindingSource>.EndEdit();
//Update the Dataset
tblAdpt.Update(tblData);
//Get the New ID from the Table Adapter
long newID = tblAdpt.Adapter.InsertCommand.LastInsertedId;
Hope this Helps ...
After inserting any row you can get last inserted id by below line of query.
INSERT INTO aspnet_GameProfiles(UserId,GameId)
VALUES(#UserId, #GameId);
SELECT ##IDENTITY
If you're using executeScalar:
cmd.ExecuteScalar();
result_id=cmd.LastInsertedId.ToString();
Maybe this answer helps as well as my database seems to have no column specified as "IDENTITY" (which is needed for "SELECT SCOPE_IDENTITY()" or "##IDENTITY" calls). Also my "ID" column was of type "binary(16)" so I needed to convert the output like stated below:
string returnId = BitConverter.ToString((byte[])cmd.ExecuteScalar()).Replace("-", "");
// skip the replace if you handle the hyphen otherwise
Use SELECT SCOPE_IDENTITY() in query
After this:
INSERT INTO aspnet_GameProfiles(UserId, GameId) OUTPUT INSERTED.ID VALUES(#UserId, #GameId)
Execute this
int id = (int)command.ExecuteScalar;
It will work
INSERT INTO aspnet_GameProfiles(UserId,GameId) VALUES(#UserId, #GameId)";
then you can just access to the last id by ordering the table in desc way.
SELECT TOP 1 UserId FROM aspnet_GameProfiles ORDER BY UserId DESC.
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
CREATE PROC [dbo].[spCountNewLastIDAnyTableRows]
(
#PassedTableName as NVarchar(255),
#PassedColumnName as NVarchar(225)
)
AS
BEGIN
DECLARE #ActualTableName AS NVarchar(255)
DECLARE #ActualColumnName as NVarchar(225)
SELECT #ActualTableName = QUOTENAME( TABLE_NAME )
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = #PassedTableName
SELECT #ActualColumnName = QUOTENAME( COLUMN_NAME )
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME = #PassedColumnName
DECLARE #sql AS NVARCHAR(MAX)
SELECT #sql = 'select MAX('+ #ActualColumnName + ') + 1 as LASTID' + ' FROM ' + #ActualTableName
EXEC(#SQL)
END
I wish to get the auto increment id from my db and call inside my controller.
The 'id' in db is primary key with auto increment.
I tried:
$id = $model->id;
$id = $model->find('id');
$id = $model->findByPK('id');
But the value is blank, any suggestion for me to get the correct id?
Reason why I need the id value is because I need id mix with other value and save into other column.
Thanks.
$newId = YourModel::find()->max('id') + 1;
AUTO_INCREMENT is a special value which may differ from the ID of the last record.
If records deleted, the AUTO_INCREMENT will still continue.
If records failed to insert, the AUTO_INCREMENT will still continue.
Assume you are using MySQL, you can see its value in phpMyAdmin.
Open a database, then a table.
Switch to the Operations tab.
Find the AUTO_INCREMENT field under Table options.
So you should obtain its value, especially when you depend on the AUTO_INCREMENT of your database.
For inserting one record, getting the LAST_INSERT_ID() could be an option. But I still don't prefer to do triple operations (insert, read ID, update). Better to minimize the I/O operations (read AUTO_INCREMENT, insert).
In my case, I need to import data from an Excel document. Surely, when performance is important, I cannot depend on the ActiveRecord model. So I use batchInsert() command.
I am adopting this answer for getting the AUTO_INCREMENT value in MySQL.
$lastModelId = Yii::$app->db->createCommand("
SELECT `AUTO_INCREMENT`
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'my_table'
")->queryScalar();
If using table prefix:
$lastModelId = Yii::$app->db->createCommand("
SELECT `AUTO_INCREMENT`
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = :TableName
")->bindValues([
':TableName' => MyModel::getTableSchema()->name,
])->queryScalar();
The easiest way would be to get the new ID after saving the record. After that you can do what you need and save it again. Sth like this:
<?
$model = new YourModel;
$model->field1 = 'some value';
$model->field2 = 'some value 2';
//...
$model->save();
// now you have the new ID and you can use it
$id = $model->id;
// do what you need e.g.
$model->field3 = $field2 + $id;
$model->save();
?>
this worked for me.
public static function getAutoIncrement($table_name)
{
$q = new Query();
$res = $q->select("AUTO_INCREMENT")
->from('INFORMATION_SCHEMA.TABLES')
->where("TABLE_SCHEMA = DATABASE() AND TABLE_NAME = '" . $table_name . "'")
->one();
if($res)
return $res["AUTO_INCREMENT"];
return false;
//or use this
//$q = "SELECT `AUTO_INCREMENT` FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = '" . $table_name . "'";
//$auto_increment = Yii::$app->db->createCommand($q)->queryScalar();
//return $auto_increment;
}
I found my own aswer:
$max = Yii::app()->db->createCommand()->select('max(id) as max')->from('TABLENAME')->queryScalar();
$id = ($max + 1);
print_r($id);
Thanks.
You are going about this the wrong way...
$model->id This is available if you have instantiated the $model prior so:
$model = new Model();
$id = $model->id; //this will work if id is the exact name of the column in db
$model->find('id') This finds elements in DB based on the id... but the syntax in wrong so it would throw an error
$model->findByPK('id') Again... find by pk returns a single row from DB if a match with the primary key (which you should have before making this call)
In conclusion, I would recommend the first way but do not forget to instantiate the model first. Otherwise, you can do something like...
$model = Model::model()->findByAttributes(array('some_attribute' => $attribute_value));
$id = $model->id;
Hope this helps!
Keep on coding!
Ares.
enter
<?php $dob=$_SESSION['dob'];
$month=$_SESSION['month'];
$exists = false;
$columns = mysql_query("show columns from $month");
while($c = mysql_fetch_assoc($columns)){
if($c['Field'] == $dob){
$exists = true;
break;
}
}
if(!$exists){
mysql_query("ALTER TABLE `$month` ADD `$dob` varchar(100) default absent");
}
$roll=$_SESSION['var'];
foreach( $roll as $value=>$roll) {
$name = mysql_real_escape_string ($roll);
$sql="insert into $month (roll) values ('$name')";
mysql_query($sql)or die(mysql_error());
}
?>
Q:-how to create a table and alter table in mysql php?
To create a table do:
CREATE TABLE `tableName` (
... Columns ...
);
cretae table:
CREATE TABLE <tablename> (<column_name <data_type>(length if_required), .... );
Alter Table:
ALTER TABLE <tablename> ADD <newcolumnname> <data_type>(length if_required);
ALTER TABLE <tablename> DROP <columnname>;
ALTER TABLE <tablename> MODIFY <columnname> <data_type>(length if_required);
Update table:
UPDATE <tablename> SET <columnname> = <value> WHERE(if_required) <condition>;
Maybe you need this? This ORM library allow you to develop DB schema on the flight. More here.
Or maybe you need so called CODE FIRST STYLE ORM LIBRARY FOR PHP? I know one but it creates/modifies/alters tables according to your class definitions:
For example if you have:
class user
{
public $id;
public $name;
}
Bu default it will create table user with fields id and name. Also that framework gives full control on field properties and table properties using doc comments. It is called db.php (http://db.php).
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
MySQL trigger to update a field to the value of id
Please I have a table with three fields :
Id (auto increment)
GroupById
Text
And I want when inserting a new row : If I left the field groupById blank, it must get by default the same value of the field Id.
Please have you any Idea ? Thanks in advance.
Edit : My code :
mysql_query("INSERT INTO group SET GroupById = (must get the current Id), Text = 'bla bla bla' ");
How about a trigger:
DELIMITER $$
CREATE TRIGGER trg_yourtable
BEFORE INSERT ON yourtable
FOR EACH ROW
BEGIN
IF NEW.GroupById IS NULL THEN
SET NEW.GroupById = (
SELECT AUTO_INCREMENT
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'yourtable'
);
END IF;
END $$
I'm not sure how safe this is... or what happens when you insert multiple rows from one query, or when two connections attempt to insert at the same time... but it works.
This simple SQL should do what you want:
INSERT INTO myTable (GroupById, Text) VALUES (NULL, 'your text');
SET #lastID = LAST_INSERT_ID();
UPDATE myTable SET GroupById = #lastID WHERE Id = #lastID;
Use a stored procedure
Get the MAX id
Add 1 to it and add insert it into both rows
You get the desired result in a single transaction.
Hope this helps.
Use this function | Tested
Example of use:
function get_current_insert_id($table)
{
$q = "SELECT LAST_INSERT_ID() FROM $table";
return mysql_num_rows(mysql_query($q)) + 1;
}
$txt = "text";
$groupID = '';
if ( empty($groupID) ) { $groupID = get_current_insert_id(test); }
$query = mysql_query("INSERT INTO test VALUES ('', '$groupID', '$txt') ");
if ( $query ) { echo 'Saved using ID:' . $groupID; } else { echo 'Oh noes!' . $query; }
Looks like you might need to run 2 queries:
insert into 'table' ('GroupById', 'Text') VALUES ('{group id}', '{sometext}')
update 'table' set GroupById = id where GroupById = null - it mightbe 0 instead of null depending on what you insert in db.
You can always optimize it through indexes, limits, order.
The current value for the columns countProductSelect and countProductInput - INTEGER NOT NULL;
Need to make INTEGER DEFAULT NULL;
PHP code below.
The problem is that when trying to update data and countProductSelect countProductInput, from the time column and countProductSelectTmp countProductInputTmp, getting the error - "no such column: countProductSelectTmp".
How to deal with this error? Or perhaps there is more educated algorithms for solving the original problem?
/**
* Updating the database
*
* #return bool
*/
protected function _updateDB()
{
$version = '3.8.4.0';
$this->_pdo->exec('
ALTER TABLE data ADD optionalCountProduct INTEGER DEFAULT NULL;
ALTER TABLE data ADD countProductSelectTmp INTEGER DEFAULT NULL;
ALTER TABLE data ADD countProductInputTmp INTEGER DEFAULT NULL;
UPDATE data SET countProductSelectTmp = countProductSelect, countProductInputTmp = countProductInput;
');
$this->_deleteSQLiteColumn(array('countProductSelect', 'countProductInput'));
// BUG
// countProductSelect and countProductInput can not get the value countProductSelectTmp and countProductInputTmp
$this->_pdo->exec('
ALTER TABLE data ADD countProductSelect INTEGER DEFAULT NULL;
ALTER TABLE data ADD countProductInput INTEGER DEFAULT NULL;
UPDATE data SET countProductSelect = countProductSelectTmp, countProductInput = countProductInputTmp;
UPDATE version SET id = "' . $version . '";
');
$this->_deleteSQLiteColumn(array('countProductSelectTmp', 'countProductInputTmp'));
return true;
}
/**
* Remove column from a SQLite Table
*
* #param array $column name of the column to remove
* #return bool
*/
protected function _deleteSQLiteColumn(array $column)
{
return (bool)$this->_pdo->exec('
BEGIN TRANSACTION;
CREATE TEMPORARY TABLE backup(' . $this->_getFullColumnsString() . ');
INSERT INTO backup SELECT ' . $this->_getShortColumnsString() . ' FROM data;
DROP TABLE data;
CREATE TABLE data(' . $this->_getFullColumnsString($column) . ');
INSERT INTO data SELECT ' . $this->_getShortColumnsString($column) . ' FROM backup;
DROP TABLE backup;
COMMIT;
');
}
From the fine manual:
PDO::exec — Execute an SQL statement and return the number of affected rows
But you're trying to execute multiple statements at once so perhaps it is only executing the last statement. Trying using exec as intended and executing your statements one at a time:
$this->_pdo->exec('ALTER TABLE data ADD optionalCountProduct INTEGER DEFAULT NULL');
$this->_pdo->exec('ALTER TABLE data ADD countProductSelectTmp INTEGER DEFAULT NULL');
$this->_pdo->exec('ALTER TABLE data ADD countProductInputTmp INTEGER DEFAULT NULL');
$this->_pdo->exec('UPDATE data SET countProductSelectTmp = countProductSelect, countProductInputTmp = countProductInput');
And then again with your next multi-statement exec and your _deleteSQLiteColumn.
As far as a better way goes, it looks like all you want to do is drop the NOT NULL constraint but SQLite's ALTER TABLE is a bit limited so your "add column, copy column, drop column via table copying" approach is the best you can do; from the SQLite FAQ:
For example, suppose you have a table named "t1" with columns names "a", "b", and "c" and that you want to delete column "c" from this table. The following steps illustrate how this could be done:
BEGIN TRANSACTION;
CREATE TEMPORARY TABLE t1_backup(a,b);
INSERT INTO t1_backup SELECT a,b FROM t1;
DROP TABLE t1;
CREATE TABLE t1(a,b);
INSERT INTO t1 SELECT a,b FROM t1_backup;
DROP TABLE t1_backup;
COMMIT;