At program startup, I'm creating a SQL Server CE table if it doesn't exist, and adding a record to it:
if (dbconn.isValidTable("hhs_settings") == -1) // <-- (IOW, it's *not* a valid table)
{
DBUtils.CreateSettingsTable();
AppSettings.WriteSettingsVal("beltprinter", "None");
}
public static void CreateSettingsTable()
{
try
{
string sqlddl =
"create table hhs_settings (setting_id int identity (1,1) Primary key, setting_name varchar(40) not null, setting_value(63) varchar not null)";
dbconn.DBCommand(sqlddl, false);
}
catch (SqlCeException sqlcex)
{
MessageBox.Show("sqlcex - CreateSettingsTable " + sqlcex.Message);
}
catch (Exception ex)
{
MessageBox.Show("CreateSettingsTable " + ex.Message);
}
}
...but then when I open a form that reads from the table:
lblSelectedPrinter.Text = AppSettings.ReadSettingsVal("beltprinter");
...it fails with "cannot find table 0"
public static string ReadSettingsVal(string settingName)
{
string retVal = string.Empty;
string sqldml = string.Format("select setting_value from hhs_settings where setting_name = {0}", " + settingName + ");
// There should only be one value returned, but using the existing getDataSet() method for now...
DataSet dsSettingVal = frmCentral.dbconn.getDataSet(sqldml);
foreach (DataRow row in dsSettingVal.Tables[0].Rows)
{
if (retVal == string.Empty)
{
retVal = row["setting_value"].ToString();
}
}
return retVal;
}
Am I missing a step here, so that the table (hhs_settings) is not being created? Or...???
UPDATE
I'm still getting the same err msg even after changing all of the goofily formatted strings so that they are now:
string sqldml = string.Format("insert into hhs_settings (setting_name, setting_value) values('{0}', '{1}')", settingName, settingVal);
string sqlqry = string.Format("select setting_value from hhs_settings where setting_name = '{0}'", settingName);
And, I'm still seeing the msg "about to create hhs_settings" even though, presumably, the createtable sql was already good:
string sqlddl =
"create table hhs_settings (setting_id int identity (1,1) Primary key, setting_name varchar(40) not null, setting_value(63) varchar not null)";
...and so, the table should have been created (which should have made the isValidTable() method return something other than -1 (the value it returns when the table is not found).
UPDATE 2
It helped (it works now) when I changed my ddl to:
string sqlddl =
"create table hhs_settings (setting_id int identity (1,1) Primary key, setting_name nvarchar(40) not null, setting_value nvarchar(63) not null)";
string.Format("select setting_value from hhs_settings where setting_name = {0}", " + settingName + ");
The result of it is
select setting_value from hhs_settings where setting_name = + settingName +
what is obviously not a correct SQL. You need to use something like this
string.Format("select setting_value from hhs_settings where setting_name = '{0}'", settingName);
(also note quotation marks around the parameter placeholder)
but it much more better if you use parameters instead of generating SQL with all identifiers embedded
If you are using stored procedures, check out the name of the passing queries in it. It should exactly match with the front end and backend.
Related
I am trying to create a table and there seems to be an issue with the schema. Please the code below, everything runs fins until the FOREIGN KEY. If I comment out the FOREIGN KEY, it creates the table but with the foreign key I get the following error:
System.Data.SqlClient.SqlException: 'Invalid object name 'Products'.
Here is my Products schema
public void CreateProductTable()
{
try
{
string tableName = "Products";
string schema = "ProductID int IDENTITY (1,1) PRIMARY KEY, " +
"ProductName VARCHAR(50) NOT NULL , " +
"ProductType VARCHAR(50) NOT NULL , " +
"ProductNumber int NOT NULL , " +
"ProductCondition VARCHAR(50) NOT NULL , " +
"ProductActiveInactive TINYINT NOT NULL , " +
"OnLoan BIT NOT NULL " +
"FOREIGN KEY(BrandID) REFERENCES ProductBrands(BrandID)";
Helper.CreateTable(tableName, schema);
}
catch (Exception e)
{
// Log errors
Console.WriteLine(e.Message);
}
}
And here is my BrandProducts schema:
public void CreateProductBrandTable()
{
try
{
string tableName = "ProductBrands";
string schema = "BrandID int IDENTITY (1,1) PRIMARY KEY, " +
"BrandName VARCHAR(50) NOT NULL";
Helper.CreateTable(tableName, schema);
}
catch (Exception e)
{
// Log errors
Console.WriteLine(e.Message);
}
}
Helper.CreateTable
public static void CreateTable(string tableName, string tableStructure)
{
string sql = $"CREATE TABLE {tableName} ({tableStructure})";
using (var connection = GetConnection())
{
try
{
connection.Execute(sql);
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
GetConnection:
public static bool DoTablesExist()
{
var connection = GetConnection();
string sql = $"SELECT COUNT(*) FROM {connection.Database}.INFORMATION_SCHEMA.TABLES" +
$" WHERE TABLE_TYPE = 'BASE TABLE'";
using (connection)
{
int number = connection.QuerySingle<int>(sql);
if (number > 0)
{
return true;
}
else
{
return false;
}
}
}
You need a BrandId column in products table in order to be able to cite it as an FK. While it would be lovely to be able to simply write FOREIGN KEY(x) REFERENCES(y) and sql server would create a column X of the same type and size as Y, it doesn't work - the column list to create needs X in it/X needs to exist first
Remember to insert your related Brand records before you try to insert your Products; a brand has to exist first so product can reference it
How do INSERT INTO Firebird, with autoincrement for the primary key?
For the table fields I have:
fstPriority VARCHAR(30), fstInfo VARCHAR(100), fstDateCreated VARCHAR(30), fstDateModified VARCHAR(30), fiKeyID INTEGER PRIMARY KEY
For the INSERT INTO I have:
FbConnection fbConn = new FbConnection(stOpenConn))
fbConn.Open();
...
FbTransaction fbTransaction = fbConn.BeginTransaction();
FbCommand fbCmd = new FbCommand("INSERT INTO " + stTableName + "(" + stFieldNames + ") VALUES ( #p0, #p1, #p2, #p3, #p4 ) RETURNING fiKeyID ", fbConn, fbTransaction);
but am uncertain what should be used for the
fbCmd.Parameters.AddWithValue
fbCmd.Parameters.AddWithValue("#p0", "1st value");
fbCmd.Parameters.AddWithValue("#p1", "2nd value");
fbCmd.Parameters.AddWithValue("#p2", "3rd value");
fbCmd.Parameters.AddWithValue("#p3", "4th value");
Then what? For fiKeyID, do I add
fbCmd.Parameters.AddWithValue("#p4", "");
Also, I see at http://www.firebirdfaq.org/faq29/ creating an autoincrement column, but am uncertain how to do this in C# ... Firebird ADO.NET ... FirebirdClient.5.8.0 ... Visual Studio 2013.
CREATE GENERATOR ...;
SET GENERATOR ...;
set term !! ;
CREATE TRIGGER ...
are not recognized by the Visual Studio compiler.
An important thing is that SET TERM is not part of the Firebird statement syntax, instead it is a client-side feature to set the statement terminator in query tools like ISQL. This terminator is necessary to know when a statement is complete and can be sent to the server. By default these tools do that on a semi-colon (;), but that doesn't work with PSQL (stored procedures, triggers), because PSQL code uses the semi-colon as well. To address this, these tools have SET TERM to switch this terminator.
Using the Firebird ADO.net provider however, you need to execute statements one at a time, so a statement terminator is irrelevant.
To be able to generate a primary key you can use the following solutions:
Firebird 3 has an identity type column, so you don't need to create a sequence and trigger yourself:
create table withgeneratedid(
id integer generated by default as identity primary key,
column2 varchar(100)
)
For Firebird 2.5 and earlier you will need to create a sequence and trigger:
create table withgeneratedid(
id integer primary key,
column2 varchar(100)
);
create sequence seq_withgeneratedid;
set term #;
create trigger withgeneratedid_bi before insert on withgeneratedid
as
begin
if (new.id is null) then new.id = next value for seq_withgeneratedid;
end#
set term ;#
When you insert values into a table and want to have a generated key, you should not include the id column in the column-list. Including the id column allows you to override the key value, but that might lead to future inserts generating a duplicate key!. If you do include the id column, then no key will be generated in the Firebird 3 example, in the Firebird 2.5 example a key will be generated if the value of the column is null, otherwise it will take the provided value.
In ADO.net you'd normally need to execute the statements individually (and not use set term). Alternatively, you could use FbScript to parse a DDL script and execute the parse statements. Note that FbScript does support (and even requires) set term.
To execute this with the Firebird ADO.net provider, you can do something like the example below. I have included three alternatives for creating the table Firebird3, Firebird2_5, and FbScriptFB2_5 (which is the same as Firebird2_5 but uses FbScript). It also show how to retrieve the generated key:
namespace FbGeneratedKeys
{
class Program
{
private static SolutionType solutionType = SolutionType.FbScriptFB2_5;
static void Main(string[] args)
{
var connectionString = new FbConnectionStringBuilder
{
Database = #"D:\temp\generatedkey.fdb",
ServerType = FbServerType.Default,
UserID = "SYSDBA",
Password = "masterkey",
}.ToString();
FbConnection.CreateDatabase(connectionString, pageSize: 8192, overwrite : true);
using (FbConnection connection = new FbConnection(connectionString))
using (FbCommand cmd = new FbCommand())
{
connection.Open();
cmd.Connection = connection;
switch (solutionType) {
case SolutionType.Firebird3:
Firebird3Example(cmd);
break;
case SolutionType.Firebird2_5:
Firebird2_5Example(cmd);
break;
case SolutionType.FbScriptFB2_5:
FbScriptFB2_5Example(cmd);
break;
}
cmd.CommandText = #"insert into withgeneratedid(column2) values (#column2) returning id";
cmd.Parameters.AddWithValue("#column2", "some value");
cmd.Parameters.Add(new FbParameter() { Direction = System.Data.ParameterDirection.Output });
cmd.ExecuteNonQuery();
Console.WriteLine("Id:" + cmd.Parameters[1].Value);
Console.ReadLine();
}
}
private static void Firebird3Example(FbCommand cmd)
{
// Firebird 3 identity column
cmd.CommandText = #"create table withgeneratedid(
id integer generated by default as identity primary key,
column2 varchar(100)
)";
cmd.ExecuteNonQuery();
}
private static void Firebird2_5Example(FbCommand cmd)
{
// Firebird 2.5 and earlier normal primary key with trigger to generate key
// Table
cmd.CommandText = #"create table withgeneratedid(
id integer primary key,
column2 varchar(100)
)";
cmd.ExecuteNonQuery();
// Sequence
cmd.CommandText = "create sequence seq_withgeneratedid";
cmd.ExecuteNonQuery();
// Trigger
cmd.CommandText = #"create trigger withgeneratedid_bi before insert on withgeneratedid
as
begin
if (new.id is null) then new.id = next value for seq_withgeneratedid;
end";
cmd.ExecuteNonQuery();
}
private static void FbScriptFB2_5Example(FbCommand cmd)
{
string script = #"
create table withgeneratedid(
id integer primary key,
column2 varchar(100)
);
create sequence seq_withgeneratedid;
set term #;
create trigger withgeneratedid_bi before insert on withgeneratedid
as
begin
if (new.id is null) then new.id = next value for seq_withgeneratedid;
end#
set term ;#
";
FbScript fbScript = new FbScript(script);
fbScript.Parse();
FbBatchExecution exec = new FbBatchExecution(cmd.Connection);
exec.AppendSqlStatements(fbScript);
exec.Execute();
}
}
enum SolutionType
{
Firebird3,
Firebird2_5,
FbScriptFB2_5
}
}
Definitions:
public const string stMAIN_TABLE_NAME = " OrgTable ";
public const string stDELETED_TABLE_NAME = " BackupTable ";
public const string stFIELD_DEFINITIONS = " fstPriority VARCHAR(30)" +
", fstInfo VARCHAR(100)" +
", fstDateCreated VARCHAR(30)" +
", fstDateModified VARCHAR(30)" +
", fiKeyID INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY ";
public const string stFIELD_NAMES = " fstPriority" +
", fstInfo" +
", fstDateCreated" +
", fstDateModified" +
", fiKeyID ";
public const string stFIELD_NAMES_NO_KEY_ID = " fstPriority" +
", fstInfo" +
", fstDateCreated" +
", fstDateModified ";
Code:
//------------------------------
static private bool boCreateDatabaseTables(string stPathFilename,
string stUserID,
string stPassword,
List<string> liststTableNames,
List<string> liststFieldDefinitions)
{
bool boErrorFlag = false;
int iTablesCount = liststTableNames.Count();
string stOpenConn = new FbConnectionStringBuilder {
Database = stPathFilename,
UserID = stUserID,
Password = stPassword,
ServerType = FbServerType.Embedded,
ClientLibrary = stCLIENT_LIBRARY
}.ToString();
using (FbConnection fbConn = new FbConnection(stOpenConn)) {
try {
fbConn.Open();
FbTransaction fbTransaction = fbConn.BeginTransaction();
for (int ii = 0; ii < iTablesCount; ii++) {
string stSql = "CREATE TABLE " + liststTableNames[ii] + "( " + liststFieldDefinitions[ii] + ")";
FbCommand fbCmd = new FbCommand(stSql, fbConn, fbTransaction);
fbCmd.ExecuteNonQuery();
}
fbTransaction.Commit();
}
catch (Exception ex) {
boErrorFlag = true;
MessageBox.Show("catch ... GlobalsFirebird ... boCreateDatabaseTables ... " + ex.Message);
}
}
return boErrorFlag;
}//boCreateDatabaseTables
//------------------------------
//------------------------------
static public bool boAddRow(string stPathFilename,
string stUserID,
string stPassword,
string stTableName,
string stFieldNamesNoKeyId,
List<string> liststFieldValuesNoKeyId)
{
bool boErrorFlag = false;
string stOpenConn = new FbConnectionStringBuilder {
Database = stPathFilename,
UserID = stUserID,
Password = stPassword,
ServerType = FbServerType.Embedded,
ClientLibrary = stCLIENT_LIBRARY
}.ToString();
using(FbConnection fbConn = new FbConnection(stOpenConn)) {
fbConn.Open();
try {
string stValuesPlaceHolder = "#p0";
for (int iii = 1; iii < liststFieldValuesNoKeyId.Count; iii++)
stValuesPlaceHolder += ", #p" + (iii).ToString();
FbTransaction fbTransaction = fbConn.BeginTransaction();
string stCmd = "INSERT INTO " + stTableName + "(" + stFieldNamesNoKeyId + ") VALUES ( " + stValuesPlaceHolder + " ) RETURNING fiKeyID ";
FbCommand fbCmd = new FbCommand(stCmd, fbConn, fbTransaction);
for (int iii = 0; iii < liststFieldValuesNoKeyId.Count; iii++) {
string stPlaceHolder = "#p" + (iii).ToString();
string stValue = liststFieldValuesNoKeyId[iii];
fbCmd.Parameters.AddWithValue(stPlaceHolder, stValue);
}
fbCmd.Parameters.Add(new FbParameter() { Direction = System.Data.ParameterDirection.Output });
fbCmd.ExecuteNonQuery();
fbTransaction.Commit();
}
catch (Exception ex) {
boErrorFlag = true;
MessageBox.Show("catch ... GlobalsFirebird ... boAddRow ... " + ex.Message);
}
}
return boErrorFlag;
}//boAddRow
//------------------------------
I am using the following code for performing a delete operation via EF code first using a inline query internally
void IRepository<T>.Delete(params Guid[] ids)
{
var sql = string.Format("UPDATE {0} SET [IsDeleted] = 1 WHERE [Id] IN (#ids) ", GetTableName());
string sep = String.Join(", ", ids.Select(x => "'" + x + "'"));
var sqlParams = new Object[]
{
new SqlParameter("ids", string.Join(",",sep)),
};
DataContext.Database.ExecuteSqlCommand(sql, sqlParams);
}
Now when I execute the command it gives me
conversion failed when converting from a character string to uniqueidentifier
error.
Hiwever when I run the query in sql say.
UPDATE [dbo].[Table] SET [IsDeleted] = 1 WHERE [Id] IN ('20Cr0BCA-6EBB-E411-A04B-BC305BA8C713','506c79c1-6ebb-e411-a04b-bc305ba8c733')
it works fine.
Is this possible to do this way ?Or what am I doing wrong ?
I would do something like this
void IRepository<T>.Delete(params Guid[] ids)
{
if (ids == null || !ids.Any())
return;
var idParams = ids.Select((x, cnt)=> new { ParamName ="#ids"+ cnt, Param = x});
var sql = string.Format("UPDATE {0} SET [IsDeleted] = 1 WHERE [Id] IN ("+ String.Join(", ",idParams.Select(x => x.ParamName)) + ") ", "Table");
var sqlParams = idParams.Select(x=> new SqlParameter(x.ParamName, x.Param)).ToArray();
DataContext.Database.ExecuteSqlCommand(sql, sqlParams);
}
I am using the code below in my C# batch job to handle a large amount (20k+) of updates and inserts. However, during testing I can see that if there is an issue, such as a constraint violation, I will only get the first error message back and no information on which record (or records) it is that caused the problem.
Is there an error handling method or technique that can be achieved either using .Net or T-SQL that could give us this functionality?
C#
private static string insertCommand =
"INSERT (ChannelCode, DrmTerrDesc, IndDistrnId, StateCode, ZipCode, EndDate, EffectiveDate, LastUpdateId, LastUpdateDate, ErrorCodes, Status) " +
"VALUES(Source.ChannelCode, Source.DrmTerrDesc, Source.IndDistrnId, Source.StateCode, Source.ZipCode, Source.EndDate, Source.EffectiveDate, Source.LastUpdateId, Source.LastUpdateDate, Source.ErrorCOdes, Source.Status)";
private static string updateCommand = "UPDATE SET Target.ChannelCode = Source.ChannelCode, Target.DrmTerrDesc = Source.DrmTerrDesc, Target.IndDistrnId = Source.IndDistrnId," +
"Target.StateCode = Source.StateCode, Target.ZipCode = Source.ZipCode, Target.EndDate = Source.EndDate, Target.EffectiveDate = Source.EffectiveDate," +
"Target.LastUpdateId = Source.LastUpdateId, Target.LastUpdateDate = Source.LastUpdateDate, Target.ErrorCodes = Source.ErrorCodes," +
"Target.Status = Source.Status ";
public static int Update(List<ZipCodeTerritory> updates, Dictionary<object, string> errorList)
{
int results = 0;
try
{
//Load updates into datatable
DataTable table = LoadData(updates, true);
//Script to create temp table
string tmpTable = "CREATE TABLE [dbo].[ZipCodeTerritoryTemp]( " +
"[ChannelCode] [char](1) NOT NULL, " +
"[DrmTerrDesc] [nvarchar](30) NOT NULL, " +
"[IndDistrnId] [char](3) NULL, " +
"[StateCode] [char](3) NOT NULL, " +
"[ZipCode] [char](9) NULL, " +
"[EndDate] [date] NOT NULL, " +
"[EffectiveDate] [date] NOT NULL, " +
"[LastUpdateId] [char](8) NULL, " +
"[LastUpdateDate] [date] NULL, " +
"[Id] [int] NULL, " +
"[ErrorCodes] [varchar](255) NULL, " +
"[Status] [char](1) NULL)";
using (SqlConnection connection = new SqlConnection(connString))
{
connection.Open();
//Create temp table
SqlCommand cmd = new SqlCommand(tmpTable, connection);
cmd.ExecuteNonQuery();
try
{
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection))
{
//Write to temp table
bulkCopy.DestinationTableName = "ZipCodeTerritoryTemp";
bulkCopy.WriteToServer(table);
//Merge changes in temp table with ZipCodeTerritory
string mergeSql = "merge ZipCodeTerritory as Target " +
"using ZipCodeTerritoryTemp as Source " +
"on " +
"Target.Id = Source.Id " +
"when matched then " +
updateCommand +
"when not matched then " +
insertCommand + ";";
cmd.CommandText = mergeSql;
results = cmd.ExecuteNonQuery();
}
}
catch (Exception ex)
{
SendEmail.ErrorMail(ex.Message);
}
finally
{
//Drop temp table
SqlCommand final = new SqlCommand("DROP TABLE [dbo].[ZipCodeTerritoryTemp]", connection);
final.ExecuteNonQuery();
}
}
}
catch (Exception ex)
{
SendEmail.ErrorMail(ex.Message);
}
return results;
}
The short answer is that you can't determine this by executing the MERGE statement, you have to check for these collisions prior to executing the MERGE.
In other words (and I can't stress this one enough): always validate your inputs.
There are two points where you can do the validation: before you bulk-copy the data to the temporary table and before you merge the temporary table into the target. Depending on the nature of your data issues you might be able to do the bulk of your validation before the data hits the server.
There are three primary classes of problems I've generally encountered with MERGE statements:
Key collisions (duplicate rows in the source)
Data format errors (e.g. string representations of dates that don't translate into DATE correctly)
Constraint failures (nulls where they're not allowed, foreign key errors, etc)
The first two can generally be detected prior to pushing the data up to the server. The third depends on the nature of your constraints... but generally we can solve these before they get to the server.
Key collisions in your data can be detected by grouping the data by the keys (Id in this case). Let's assume that you have two records with the same Id value, but you want to merge in the one with the highest LastUpdateDate. One option for this is:
var cleanupdates =
from update in updates
group update by update.Id into grp
select grp.OrderByDescending(u => u.LastUpdateDate).First();
If your constraint problems are related to null values, filter out those records that have invalid nulls using a where clause. If they're related to foreign key constraints, load those keys into a list and filter on them. You can cover a lot of the validation using LINQ queries.
The important point is that you do the validation. Otherwise your MERGE will fail, and you won't know why.
For your Merge statement you are missing one little thing
merge ZipCodeTerritory as Target " +
"using (SELECT * FROM ZipCodeTerritoryTemp) as Source " + --<-- need to select data
"on " +
"Target.Id = Source.Id " +
"when matched then " +
updateCommand +
"when not matched then " +
insertCommand + ";";
But before you go ahead with this approach Read This article from Aaron Bertrand about issues with MERGE Statement.
I would suggest you to to use IF EXISTS Method something like this ...
Update
UPDATE T
SET T.Col1 = S.Col1,
T.Col2 = S.Col2,
T.Col3 = S.Col3
FROM ZipCodeTerritory T INNER JOIN ZipCodeTerritoryTemp S
ON T.id = S.id
INSERT
INSERT INTO ZipCodeTerritory(Col1, Col2, Col3, ....)
SELECT S.Col1, S.Col2, S.Col3, ....
FROM ZipCodeTerritoryTemp S LEFT JOIN ZipCodeTerritory T
ON S.ID = T.ID
WHERE T.ID IS NULL
I am absolutly new in C# (I came from Java) and I have the following problem
I have a method that execute an INSERT query to insert a new record into the table that is univocallu identify by an Id (the primary key)
So my table have some fields including: Id and VulnerabilityAllertId.
These two fields must have the same value.
At this time my method that perform the INSERT query work in this way:
I pass a VulnsSmall model object to the method and it create a new record in the table with each fields having the value of the related field in the model object
public void insert(DataModel.Vulnerability.VulnSmall v) {
_strSQL = "";
string strSQLParametri = "";
string query = "";
System.Data.Common.DbCommand command;
command = _connection.CreateCommand();
// [VulnerabilityAlertId] insertion on the DB:
if (v.VulnerabilityAlertId != null) {
_strSQL = "INSERT INTO VulnerabilityAlertDocument ( [VulnerabilityAlertId] ";
strSQLParametri = " VALUES (#VULNERABILITYALERTID ";
addParameter(command, "#VULNERABILITYALERTID ", v.Id);
}
// [SourceId] insertion on the DB:
if (!String.IsNullOrEmpty(v.SourceId))
{
_strSQL += ",[SourceId] ";
strSQLParametri += ", #SOURCEID ";
addParameter(command, "#SOURCEID", v.SourceId);
}
.................................
.................................
.................................
// [Language] insertion on the DB:
if (v.Language != null)
{
_strSQL += ",[Language] ";
strSQLParametri += ", #LANGUAGE ";
addParameter(command, "#LANGUAGE", v.Language);
}
query = _strSQL + " ) " + strSQLParametri + " );";
command.CommandText = query;
_executeNoQuery(command);
}
My problem is that this code section is wrong:
// [VulnerabilityAlertId] insertion on the DB:
if (v.VulnerabilityAlertId != null) {
_strSQL = "INSERT INTO VulnerabilityAlertDocument ( [VulnerabilityAlertId] ";
strSQLParametri = " VALUES (#VULNERABILITYALERTID ";
addParameter(command, "#VULNERABILITYALERTID ", v.Id);
}
It is wrong because, in the database VulnerabilityAlertDocument ** table the **[VulnerabilityAlertId] column must have the same value of the Id primary key that is auto increment
In my previous code it use the value into v.VulnerabilityAlertId model field to set the [VulnerabilityAlertId] column value for my new row, so it have not the same value of the Id primary key column
What can I do to set the same value of the [Id] autoincrement column for the [VulnerabilityAlertId] column in my new row?
If i get your query correctly,
you can make changes at database level
by adding a mirror column to the primary key.
ALTER TABLE VulnerabilityAlertDocument
ADD mirror AS [Id] UNIQUE
and then you have a column which always replicate the value of primary.
You can use IDENT_CURRENT:
CREATE TABLE test_identity
(
id int identity(1,1) primary key,
letter nvarchar(1),
value int DEFAULT(IDENT_CURRENT('test_identity'))
)
PRINT IDENT_CURRENT('test_identity')
INSERT INTO test_identity(letter) VALUES ('a')
INSERT INTO test_identity(letter) VALUES ('b')
INSERT INTO test_identity(letter) VALUES ('c')
INSERT INTO test_identity(letter) VALUES ('d')
SELECT * FROM test_identity
DROP TABLE test_identity