I call the procedure with php and the relevant variables. I need the latest IDs to use it for the next insert, so I set variables with SCOPE_IDENTITY. The return ist always the value of appointment_id ?!
ALTER proc [dbo].[insertPersonWithCmoFmo]
#appointment_id int,
#kostenstelle varchar(50),
#vorname varchar(50),
#nachname varchar(50),
#ci_nummer int,
#anzahl_monitore_old int,
#raum varchar(50),
#gebäude varchar(50),
#bemerkung text,
#hardware_typ varchar(50),
#anzahl_monitore_new varchar(50),
#zubehör text
as
DECLARE
#latestPersonID int,
#latestCmoID int,
#latestFmoID int
BEGIN
INSERT INTO [RC.Persons] (kostenstelle, vorname, nachname) VALUES (#kostenstelle, #vorname, #nachname);
SET #latestPersonID = (SELECT SCOPE_IDENTITY())
INSERT INTO [RC.CMO] (ci_nummer, anzahl_monitore, raum, gebäude, bemerkung) values (#ci_nummer, #anzahl_monitore_old, #raum, #gebäude, #bemerkung);
SET #latestCmoID = (SELECT SCOPE_IDENTITY())
INSERT INTO [RC.FMO] (hardware_typ, anzahl_monitore, zubehör) values (#hardware_typ, #anzahl_monitore_new, #zubehör);
SET #latestFmoID = (SELECT SCOPE_IDENTITY())
INSERT INTO [RC.Appointments_RC.CMO] (cmo_id, appointment_id) values (#latestCmoID, #appointment_id);
INSERT INTO [RC.Persons_RC.CMO] (cmo_id, person_id) VALUES (#latestCmoID, #latestPersonID);
INSERT INTO [RC.Persons_RC.FMO] (fmo_id, person_id) VALUES (#latestFmoID, #latestPersonID);
return #latestFmoID
END
This is the exec code. Why the is a "N" before all varchar type?
USE [Testtable]
GO
DECLARE #return_value int
EXEC #return_value = [dbo].[insertPersonWithCmoFmo]
#appointment_id = 52,
#kostenstelle = N'54',
#vorname = N'testname',
#nachname = N'testlastname',
#ci_nummer = 111222333,
#anzahl_monitore_old = 2,
#raum = N'255',
#gebäude = N'KWA12',
#bemerkung = N'blablabla',
#hardware_typ = N'Desktop',
#anzahl_monitore_new = N'4',
#zubehör = N'Test'
SELECT 'Return Value' = #return_value
GO
SQL Output:
Meldung 2601, Ebene 14, Status 1, Prozedur insertPersonWithCmoFmo, Zeile 36
Cannot insert duplicate key row in object 'dbo.RC.FMO' with unique index 'NonClusteredIndex-20140116-143317'. The duplicate key value is ().
The statement has been terminated.
Is there something about the error message you don't understand? One or more of the tables has a unique constraint (or index) and you are trying to insert the same values in the table. For example, the persons table might already have the person in it.
The N before the string explicitly makes the string use wide characters.
Your stored procedure probably needs to be rewritten. You need to check errors that might occur along the way. Traditionally, a value would be returned using an OUTPUT parameter.
The safest way to get the new id value is to use the output clause of the insert statement (see the documentation here).
The N indicates nvarchar instead of varchar.
See:
https://stackoverflow.com/questions/10025032/what-is-the-meaning-of-the-prefix-n-in-t-sql-statements
Related
I want to use one form to insert into two different Microsoft sql tables. I tryed to use 2 inserts, but didnt work.
if (isset($_GET['submit'])) {
$sth = $connection->prepare("INSERT INTO DB.dbo.Fehler (QualiID, TestaufstellungID, ModulinfoID, failAfter, Datum, Verbleib, DUTNr) VALUES ($QualiID, $TestaufstellungID,$ModulinfoID,'$failAfter','$Datum','$Verbleib','$DUTNr')");
echo "INSERT INTO DB.dbo.Fehler (QualiID, TestaufstellungID, ModulinfoID, failAfter, Datum, Verbleib, DUTNr) VALUES ($QualiID, $TestaufstellungID,$ModulinfoID,'$failAfter',$Datum,'$Verbleib','$DUTNr')";
$sth->execute();
if($sth)
{
echo "";
}
else
{
echo sqlsrv_errors();
}
$MID = $connection->prepare("MAX(MID) as MID FROM DB.dbo.Fehler WHERE DB.dbo.Fehler.TestaufstellungID = '". $TestaufstellungID . "'");
$MID->execute();
$sth2 = $connection->prepare("INSERT INTO DB.dbo.Fehlerinfo (MID, Tester, Test, Ausfallbedingungen, Fehlerbeschreibung, Ersteller) VALUES ($MID, '$Tester','$Test','$Ausfallbedingungen','$Fehlerbeschreibung','$Ersteller')");
$sth2->execute();
To understand MID is the Primary key of table Fehler and ist the foreign key in the second table Fehlerinfo
Thats why i have the select work around to get the last MID and want to save it in a variable $MID to insert it into the second table.
Is there a smarter solution possible?
As I mentioned in the comments, generally the better way is to do the insert in one batch. This is very over simplified, however, should put you in the right direction. Normally you would likely be passing the values for the Foreign Table in a Table Value Parameter (due to the Many to One relationship) and would encapsulate the entire thing in a TRY...CATCH and possibly a stored procedure.
I can't write this in PHP, as my knowledge of it is rudimentary, but this should get you on the right path to understanding:
USE Sandbox;
--Couple of sample tables
CREATE TABLE dbo.PrimaryTable (SomeID int IDENTITY(1,1),
SomeString varchar(10),
CONSTRAINT PK_PTID PRIMARY KEY NONCLUSTERED (SomeID));
CREATE TABLE dbo.ForeignTable (AnotherID int IDENTITY(1,1),
ForeignID int,
AnotherString varchar(10),
CONSTRAINT PK_FTID PRIMARY KEY NONCLUSTERED(AnotherID),
CONSTRAINT FK_FTPT FOREIGN KEY (ForeignID)
REFERENCES dbo.PrimaryTable(SomeID));
GO
--single batch example
--Declare input parameters and give some values
--These would be the values coming from your application
DECLARE #SomeString varchar(10) = 'abc',
#AnotherString varchar(10) = 'def';
--Create a temp table or variable for the output of the ID
DECLARE #ID table (ID int);
--Insert the data and get the ID at the same time:
INSERT INTO dbo.PrimaryTable (SomeString)
OUTPUT inserted.SomeID
INTO #ID
SELECT #SomeString;
--#ID now has the inserted ID(s)
--Use it to insert into the other table
INSERT INTO dbo.ForeignTable (ForeignID,AnotherString)
SELECT ID,
#AnotherString
FROM #ID;
GO
--Check the data:
SELECT *
FROM dbo.PrimaryTable PT
JOIN dbo.ForeignTable FT ON PT.SomeID = FT.ForeignID;
GO
--Clean up
DROP TABLE dbo.ForeignTable;
DROP TABLE dbo.PrimaryTable;
As i mentioned the answer how it works for me fine atm.
if (isset($_GET['submit'])) {
$failInsert = ("INSERT INTO DB.dbo.Fehler (QualiID, TestaufstellungID, ModulinfoID, failAfter, Datum, Verbleib, DUTNr) VALUES ($QualiID, $TestaufstellungID,$ModulinfoID,'$failAfter','$Datum','$Verbleib','$DUTNr')");
$failInsert .= ("INSERT INTO DB.dbo.Fehlerinfo (MID, Tester, Test, Ausfallbedingungen, Fehlerbeschreibung, Ersteller) VALUES (NULL, '$Tester','$Test','$Ausfallbedingungen','$Fehlerbeschreibung','$Ersteller')");
$failInsert .= ("UPDATE DB.dbo.Fehlerinfo SET DB.dbo.Fehlerinfo.MID = i.MID FROM (SELECT MAX(MID)as MID FROM DB.dbo.Fehler) i WHERE DB.dbo.Fehlerinfo.TestID = ( SELECT MAX(TestID) as TestID FROM DB.dbo.Fehlerinfo)");
$sth = $connection->prepare($failInsert);
$sth->execute();
}
I have a stored procedure as below
DROP PROCEDURE IF EXISTS maintain//
CREATE PROCEDURE maintain
(
IN inMaintainType CHAR(1), -- 'i' = Insert, 'u'= Update/Edit, 'd'= Delete
IN inEntityId INT, -- 0 for Insert Case
IN inEntityName VARCHAR(100),
IN inEntityDescription VARCHAR(100),
IN inEntityPrefix CHAR(1),
IN inStatus CHAR(1), -- 'a' = Active, 'i' = Not active
IN inEmpId INT,
OUT outReturnStatus INT,
OUT outReturnRemarks VARCHAR(100)
)
BEGIN
IF inMaintainType= 'i'
THEN
INSERT INTO Entity
(
EntityId,
EntityName,
EntityDescription,
EntityPrefix,
Status,
CreatedBy,
CreatedDate,
ModifiedBy,
ModifiedDate
)
VALUES
(
li_EntityId,
inEntityName,
inEntityDescription,
inEntityPrefix,
'a',
inEmpId,
now(),
inEmpId,
now()
);
if row_count() != 0
THEN SET outReturnStatus =0 ,
outReturnRemarks = 'Insert Successful';
ELSE SET outReturnStatus = 1,
outReturnRemarks = 'Insert Not Successful';
END IF;
END IF ;
I want to call the procedure to insert data with variables
mysql_query("CALL maintain('i','$EntityId','$EntityName','$EntityDescription','$EntityPrefix','$Status','$EmpId',#outvari1,#outvari2)")or die(mysql_error());
But it's showing me the error
Unknown column 'li_EntityId' in 'field list'
EntityId is the auto incremented field.
To clarify the comments above into an actual answer...
You have set up your table so that the field EntityId will Auto-Increment.
Because of this when you insert a record into the table you don't need to explicitly add a value for the ID field - it will do it for you.
The solution is therefore to remove the EntityId field from the INSERT INTO ... statement, and to remove the li_EntityId value from the inserted values, so only 8 arguments are passed into the remaining 8 fields.
I am new to SQL Server. I have created a script where I import data and insert into SQL Server. The update query works fine but the insert query does not . I get a error
Error converting data type varchar to float.. INSERT INTO dbo.
This is the code
$amount = trim(str_replace('$','',$data[2]));
// echo ($amount); // prints 1,000,000.00
// INSERT QUERY
//Try 1 : Fails
$Query = "INSERT INTO dbo.testtable (id, name, amount)
values ( 11, 'John' , $amount )";
//Try 2 : Fails
$Query = "INSERT INTO dbo.testtable (id, name, amount)
values ( 11, 'John' , CONVERT(FLOAT,'$amount') )";
How in the world can I insert a proper float value from the variable ($amount) into SQL Server?
use this:
cast('$amount' as money)
Updates:
It actually depends on what's the type of your column amount. If it's varchar, it should not throw an error for 1st line. So, I guess it's something like decimal(18, 2). Refer to the demo here
declare #amount varchar(25)
SET #amount = '1,000.00'
create table #tmp_money (amount FLOAT)
insert into #tmp_money
SELECT cast(#amount as money)
select * from #tmp_money
create table cmu_patient
( patient_id character varying(13) NOT NULL,
patient_hn character varying(7),
patient_fname character varying(50),
patient_lname character varying(50),
home_id integer,
CONSTRAINT cmu_patient_pkey PRIMARY KEY (patient_id),
CONSTRAINT Fk_home FOREIGN KEY(home_id)
REFERENCES cmu_home(home_id)
);
create table cmu_treatment
( treatment_id serial NOT NULL,
treatment_date date,
treatment_time time without time zone,
treatment_typecome character varying(100),
treatment_detail text,
patient_id character varying(13),
appointment_id character varying(5),
transfer_id character varying(5),
res_users_id integer,
CONSTRAINT cmu_treatment_pkey PRIMARY KEY (treatment_id),
CONSTRAINT Fk_patient FOREIGN KEY(patient_id)
REFERENCES cmu_patient(patient_id),
CONSTRAINT Fk_user_id FOREIGN KEY(res_users_id)
REFERENCES res_users(id)
);
$treatment_date = $GET_[...];
$treatment_time = $GET_[...];
$treatment_typecome = $GET_[...];
$treatment_note = $GET_[...];
$CID = $GET_[...];
this code -------- it's incorrect
INSERT INTO cmu_treatment(treatment_id, treatment_date, treatment_time,
treatment_typecome, treatment_detail, patient_id, appointment_id,transfer_id, res_users_id)
VALUES(NULL,'".$tratment_date."','".$treatment_time."','".
$treatment_typecome."','".$treatment_note."','".$CID."',NULL,NULL,NULL)
WHERE cmu_patient.patient_id = cmu_treatment.patient_id ;
i think that's wrong
i don't know if i want to write insert data into table with where cause i should write sql ?
thank :)
I suspect what you really want is an update, to change existing values in an existing record:
update cmu_treatment
set treatment_date = $treatment_date,
treatment_time = $treatment_time,
treatment_detail = $treatment_typecome,
treatment_note = $treatment_note
where patient_id = $CID;
(I'm leaving out the NULL values on the assumption that those shouldn't really change.)
If you do indeed want a new record, you can do:
INSERT INTO cmu_treatment(treatment_id, treatment_date, treatment_time,
treatment_typecome, treatment_detail, patient_id, appointment_id,
transfer_id, res_users_id
)
select NULL,'".$tratment_date."', '".$treatment_time."','".
$treatment_typecome."','".$treatment_note."','".$CID."', NULL, NULL, NULL;
You can write an INSERT statement populating target table with a SELECT statement. In the SELECT statement you can use WHERE condition.
So instead this query:
INSERT INTO table VALUES (....)
You must write:
INSERT INTO table
SELECT fields
FROM anothertable
WHERE condition
In your case, I think you must use an INSERT without WHERE condition if you want to insert only a row in your treatment table.
Tell me if you want to know further info
EDIT After comment
IMHO your statement must be:
INSERT INTO cmu_treatment
(treatment_id, treatment_date, treatment_time,
treatment_typecome, treatment_detail, patient_id, appointment_id,
transfer_id, res_users_id)
VALUES
(NULL,'".$tratment_date."','".$treatment_time."',
'".$treatment_typecome."','".$treatment_note."','".$CID."',NULL,NULL,NULL)
INSERT INTO `cmu_treatment`(`treatment_id`, `treatment_date`, `treatment_time`,
`treatment_typecome`, `treatment_detail`, `patient_id`, `appointment_id`,`transfer_id`, `res_users_id`)
VALUES(NULL,'".$tratment_date."','".$treatment_time."','".
$treatment_typecome."','".$treatment_note."','".$CID."',NULL,NULL,NULL)
WHERE `cmu_patient.patient_id` = `cmu_treatment.patient_id` ;
And you don't need (table name).(column).
Is this Inside "" ? If yes then you don't need '".$tratment_date."' you can use only '' so your code will look like this.
INSERT INTO cmu_treatment(treatment_id, treatment_date, treatment_time,
treatment_typecome, treatment_detail, patient_id, appointment_id,transfer_id, res_users_id)
VALUES(NULL,'$tratment_date','$treatment_time','
$treatment_typecome','$treatment_note','$CID',NULL,NULL,NULL)
WHERE `patient_id` = patient_id ;
And finally what is patient_id? Is it variable? If not IT MUST BE. Don't give same names to different things.
I have problem in updating mysql table. While the problem seems somewhat strange I'm explaining it below.
I am working on user's profile update in which the data from single form is inserting/updating to two different tables but if i update the whole form information then updating data is successful but if i only update some 2 or 3 fields then updation is fail. I'm using mysql stored procedure for sql update the code is as under...
DELIMITER $$
DROP PROCEDURE IF EXISTS `usp_user_profile_save` $$
CREATE PROCEDURE `usp_user_profile_save`(IN sIntro_para VARCHAR(255), IN sBook VARCHAR(255), IN sProfileNewName VARCHAR(255),
IN iRel VARCHAR(255), IN iBdate VARCHAR(255), IN iSO INT, IN iMerital_status INT, IN iChildren INT, IN iProfession INT,
IN iIncome INT, IN iIncome_unit INT, IN iCountry INT, IN iState INT, IN iCity_or_post_code INT, IN iHeight VARCHAR(255), IN iSp INT, IN iEthnicity INT,
IN iHair_color INT, IN iHair_lenght INT, IN iEye_color INT, IN iSmoker_or_not INT, IN iUserId INT)
BEGIN
DECLARE n,n1,respCode INT;
DECLARE respMsg,dbg VARCHAR(255);
START TRANSACTION;
UPDATE `tbl_user` SET
`introduction` = sIntro_para,
`profile_picture` = sProfileNewName,
`birthdate` = iBdate,
`s_o` = iSO,
`marital_status` = iMerital_status,
`children` = iChildren,
`profession` = iProfession,
`income` = iIncome,
`income_unit` = iIncome_unit,
`my_book` = sBook,
`r_s` = iRel,
`counrty` = iCountry,
`state` = iState,
`city` = iCity_or_post_code,
`modified` = NOW(),
`modified_by` = iUserId
WHERE `id` = iUserId;
SET n = ROW_COUNT();
IF n <= 0 THEN
ROLLBACK;
ELSE
IF EXISTS (SELECT * FROM `tbl_user_physical` WHERE `tbl_user_id` = iUserId) THEN
UPDATE `tbl_user_physical` SET
`tbl_user_id` = iUserId,
`height` = iHeight,
`shape` = iSp,
`ethnicity` = iEthnicity,
`hair_color` = iHair_color,
`hair_length` = iHair_lenght,
`eye_color` = iEye_color,
`smoker_or_non_smoker` = iSmoker_or_not
WHERE `tbl_user_id` = iUserId;
SET n1 = ROW_COUNT();
ELSE
INSERT INTO `tbl_user_physical`(`tbl_user_id`, `height`, `shape`, `ethnicity`, `hair_color`, `hair_length`, `eye_color`, `smoker_or_non_smoker`) VALUES (iUserId, iHeight, iSp, iEthnicity, iHair_color, iHair_lenght, iEye_color, iSmoker_or_not);
SET n1 = LAST_INSERT_ID();
END IF;
IF n1 > 0 THEN
COMMIT;
SELECT 1 AS respCode, 'Registration successfull.' AS respMsg;
ELSE
ROLLBACK;
SELECT 0 AS respCode,'Registration couldn\'t be completed.' AS respMsg, n, n1;
END IF;
END IF;
END $$
DELIMITER;
Though i have googled my question many time with different keywords but i dont find relevant questions as mine, I have written update statement correctly but its not updating because most of the new data which is going to be update is same as old and my senior said me that update only work if there is a new set of data is submitted and used..
so, please help me to solve this problem
thanks in advance..
I lately come to know that UPDATE statement return error if we update same data. So, I've update added new column modified_date and updating this field with NOW() so that at least one column got changed and UPDATE statement returns no error.