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
Related
Error Message showing up after trying to call foreign key, that is a primary key in another table.
There's two tables and whats supposed to link them is the foreign key.
The SQL Server database does not allow, making the identity of both the primary key and the foreign key to true so it can auto increment
System.Data.SqlClient.SqlException HResult=0x80131904 Message=Cannot insert the value NULL into column 'client_ID', table ; column does not allow nulls.
Code for the database class:
public static void AddVehicle(string serial_Number, string Make, string Model, string Year, string Color)
{
string insStmt = "INSERT INTO VEHICLE (serial_Number, Make, Model, Year, Color) VALUES (#serial_Number, #Make, #Model, #Year, #Color)";
SqlConnection conn = GetConnection();
SqlCommand insCmd = new SqlCommand(insStmt, conn);
insCmd.Parameters.AddWithValue("#serial_Number", serial_Number);
insCmd.Parameters.AddWithValue("#Make", Make);
insCmd.Parameters.AddWithValue("#Model", Model);
insCmd.Parameters.AddWithValue("#Year", Year);
insCmd.Parameters.AddWithValue("#Color", Color);
try
{
conn.Open();
insCmd.ExecuteNonQuery();
}
catch (SqlException ex)
{
throw ex;
}
finally
{
conn.Close();
}
}
public static List<Vehicle> GetVehicle()
{
List<Vehicle> vehicleList = new List<Vehicle>();
SqlConnection conn = GetConnection();
string selStmt = "SELECT * FROM VEHICLE ORDER BY Make, Model";
SqlCommand selcCmd = new SqlCommand(selStmt, conn);
try
{
conn.Open();
SqlDataReader reader = selcCmd.ExecuteReader();
while (reader.Read())
{
Vehicle vehicle = new Vehicle();
//vehicle.Vehicle_ID = (int)reader["Vehicle_ID"];
vehicle.Vehicle_ID = reader["Vehicle_ID"].ToString();
vehicle.Serial_Number = reader["Serial_Number"].ToString();
vehicle.MAke = reader["MAke"].ToString();
vehicle.MOdel = reader["MOdel"].ToString();
vehicle.YEar = reader["YEar"].ToString();
vehicle.COlor = reader["COlor"].ToString();
vehicle.ClientID = (int)reader["ClientID"];
vehicleList.Add(vehicle);
}
reader.Close();
}
catch (SqlException ex) { throw ex; }
finally { conn.Close(); }
return vehicleList;
}
Code for the windows form is:
private void Form2_Load(object sender, EventArgs e)
{
listView.Items.Clear();
List<Vehicle> vehicleList;
try
{
vehicleList = CARDB.GetVehicle();
if (vehicleList.Count > 0)
{
Vehicle vehicle;
for (int i = 0; i < vehicleList.Count; i++)
{
vehicle = vehicleList[i];
//listView.Items.Add(vehicle.Vehicle_ID.ToString());
listView.Items[i].SubItems.Add(vehicle.Vehicle_ID);
listView.Items[i].SubItems.Add(vehicle.Serial_Number);
listView.Items[i].SubItems.Add(vehicle.MAke);
listView.Items[i].SubItems.Add(vehicle.MOdel);
listView.Items[i].SubItems.Add(vehicle.YEar);
listView.Items[i].SubItems.Add(vehicle.COlor);
listView.Items.Add(vehicle.ClientID.ToString());
}
}
//else { MessageBox.Show("Enter client Details", "Alert:");}
}
catch (Exception ex) { MessageBox.Show(ex.Message, ex.GetType().ToString()); }
}
private void btnSubmit2_Click(object sender, EventArgs e)
{
CARDB.AddVehicle(txtSerialNumber.Text, txtMake.Text, txtModel.Text, txtYear.Text, txtColor.Text);
txtSerialNumber.Text = "";
txtMake.Text = "";
txtModel.Text = "";
txtYear.Text = "";
txtColor.Text = "";
this.Form2_Load(this, null);
}
SQL code for the table is:
CREATE TABLE [dbo].[Vehicle]
(
[Vehicle_ID] INT IDENTITY (1, 1) NOT NULL,
[client_ID] INT NOT NULL,
[Serial_Number] NVARCHAR(MAX) NULL,
[Make] NVARCHAR(MAX) NULL,
[Model] NVARCHAR(MAX) NULL,
[Year] NVARCHAR(MAX) NULL,
[Color] NVARCHAR(MAX) NULL,
PRIMARY KEY CLUSTERED ([Vehicle_ID] ASC),
CONSTRAINT [FK_Vehicle_Client]
FOREIGN KEY ([client_ID]) REFERENCES [dbo].[Client] ([clientID])
);
Your error is in this function as I see :
public static void AddVehicle(string client_ID,string serial_Number, string Make, string Model, string
Year, string Color)
{
string insStmt = "INSERT INTO VEHICLE (client_ID,serial_Number, Make, Model, Year, Color)
VALUES (#client_ID,#serial_Number, #Make, #Model, #Year, #Color)";
SqlConnection conn = GetConnection();
SqlCommand insCmd = new SqlCommand(insStmt, conn);
insCmd.Parameters.AddWithValue("#client_ID", client_ID);
insCmd.Parameters.AddWithValue("#serial_Number", serial_Number);
insCmd.Parameters.AddWithValue("#Make", Make);
insCmd.Parameters.AddWithValue("#Model", Model);
insCmd.Parameters.AddWithValue("#Year", Year);
insCmd.Parameters.AddWithValue("#Color", Color);
try
{
conn.Open();
insCmd.ExecuteNonQuery();
}
catch (SqlException ex)
{
throw ex;
}
finally
{
conn.Close();
}
}
You are missing the client_ID in the insert SQL statement, hence you get the error of Client Id being null.
You need to pass client_ID to the Add Vehicle function or your function INSERT statement will definitely fail.
Developers, I am new to programming and c# coding I written a code to insert the Xml data into database and it is working perfect but my requirement in code is "if table is not exists create a new table with same columns in the DataBase and insert the data " so how can I write the code ?
public void SaveXmltoDB(List<MeterReading> MeterReadingList)
{
//OpenConnection();
// CreateTableIfNotExists();
foreach (var meterReading in MeterReadingList)
{
foreach(var interval in meterReading.IntervalDatalist)
{
foreach(var reading in interval.Readinglist)
{
string command = string.Format("insert into INTERVALDATA1(SerialNumber,TimeStamp,MeterData) VALUES ({0},'{1}',{2})", meterReading.MeterName, reading.TimeStamp.ToString(), reading.RawReading);
using (SqlConnection conn = new SqlConnection("server=LAPTOP-N6V52QKD\\AKHIL5656;" +
"Trusted_Connection=yes;" +
"database=ReportServer$AKHIL5656; " +
"connection timeout=30;" + "persist security info = True;" +
"Integrated Security = SSPI;"))
{
SqlCommand myCommand = new SqlCommand(command,conn);
myCommand.CommandType = System.Data.CommandType.Text;
conn.Open();
try
{
myCommand.ExecuteNonQuery();
}
catch (Exception ex)
{
}
}
}
}
}
CloseConnection();
}
The above code is perfectly working to insert the data into my table ,In the above code how can I program If table not exists in the database create new table with same columns and insert the data?
can anyone help me on this?
Thanks,
I think this works for SQLServer and MYSQL:
Select * From Information_Schema.Tables Where Table_Name = 'TableName';
This returns all tables matching your name--1 row if the table exists, no rows if it doesn't.
I'm sure the fields returned can be reduced but since it's returning only one row I have never worried about it.
Here is summary of a code that I wrote yesterday with a few changes for the answer.
in the beginning the program checks if the table exist, using INFORMATION_SCHEMA.TABLES.
if the table is not exist it will be create with
createTableQuery field that represents the command for creating the new table. replace col1 col2 col 3... etc with your columns (SerialNumber,TimeStamp,MeterData... etc) replace the data types and use IDENTITY (1, 1) command if you need incremental value.
private void saveTableToDataBase()
{
string tableName = dbTableName;
// check if table exist in sql server db
if (IsTableExistInDb(tableName) == true) {
// table exist do something...
} else {
// create table, replace with your column names and data types
string createTableQuery = "CREATE TABLE " & "." & tableName & "(" & _
"ID int IDENTITY (1, 1) NOT NULL PRIMARY KEY, " & _
"Col1 int, " & _
"Col2 decimal(5,4), " & _
"Col3 int, " & _
"Col4 decimal(5,4), " & _
"Col5 int " & _
")"
// create table in database
Insert(createTableQuery);
}
}
public static Boolean IsTableExistInDb(string tableName)
{
Object result = ExecuteScalarWithAnonimusType("SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = " + "'" + tableName + "'", Con);
if (result != null && byte.Parse(result.ToString()) == 1)
{
return true;
}
else
{
return false;
}
}
public static object ExecuteScalarWithAnonimusType(string query)
{
Cmd = new SqlCommand(query, Con);
try
{
return Cmd.ExecuteScalar();
}
catch (Exception ex)
{
return null;
}
finally
{
if (Con.State != ConnectionState.Closed)
Con.Close(); Con.Close();
}
}
public static bool Insert(string command)
{
try {
con = new SqlConnection(System_Vars.SqlClientConnString);
con.Open();
cmd = new SqlCommand(command, con);
return cmd.ExecuteNonQuery();
} catch (Exception ex) {
return false;
} finally {
con.Close();
}
}
You don't want to try and do a create table from string SQL. I mean you could create stored procedure and then call it from code. But you probably want to do this during application setup program and not when the application runs.
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 have written a unique ID generating function that generates a ID every time a new row is inserted into the database. But sometimes it gives same ID for every row. I can't find out what is the problem exactly happening that time. I give you the code for insert into database and code for ID generate. Please review the code and tell me if there is any logical error or not-
// Daily sales report entry codeing…………………………………………………………………………………………………………………
public string GetSalesTeam(SalesTeam st)
{
try
{
SqlConnection con = SqlConnDAC.CreateConn();
SqlCommand cmd = new SqlCommand("Insert into DSR values(#v1,#v2,#v3,#v4,#v5,#v6,#v7,#v8,#v9,#v10,#v11,#v12,#v13,#v14,#v15,#v16)", con);
IDGen.varr = DSR_IDGen(); //Calling id generate function
cmd.Parameters.AddWithValue("#v1", st.Sl_No);
cmd.Parameters.AddWithValue("#v2", st.User_ID);
cmd.Parameters.AddWithValue("#v3", st.Name);
cmd.Parameters.AddWithValue("#v4", st.Branch);
cmd.Parameters.AddWithValue("#v5", st.Desg);
cmd.Parameters.AddWithValue("#v6", st.Visiting_Date);
cmd.Parameters.AddWithValue("#v7", st.Name_Of_Client);
cmd.Parameters.AddWithValue("#v8", st.Address);
cmd.Parameters.AddWithValue("#v9", st.PhNo);
cmd.Parameters.AddWithValue("#v10",Convert.ToInt32(st.QuoteValue));
cmd.Parameters.AddWithValue("#v11", st.Remarks);
cmd.Parameters.AddWithValue("#v12", st.Source);
cmd.Parameters.AddWithValue("#v13",IDGen.varr);
cmd.Parameters.AddWithValue("#v14", st.Month);
cmd.Parameters.AddWithValue("#v15", st.Year);
cmd.Parameters.AddWithValue("#v16",Convert.ToInt32(st.ClosedValue));
// cmd.Parameters.AddWithValue("#v17", st.TypeOfCall);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
return "Success and DSR No.for_ "+st.Name_Of_Client+" = "+IDGen.varr+"";
}
catch (Exception e)
{
return e.ToString();
}
}
//ID generate function………………………………………………………..
public string DSR_IDGen()
{
int i = 0;
string temp;
string var;
var = ("DSR-" + i.ToString()).Trim();
SqlConnection conID = SqlConnDAC.CreateConn();
SqlCommand cmdd = new SqlCommand("select DSR_No from DSR", conID);
conID.Open();
SqlDataReader dr = cmdd.ExecuteReader();
while (dr.Read())
{
temp = (dr[0].ToString()).Trim();
if (var == temp)
{
i = i + 1;
var = ("DSR-" + i.ToString()).Trim();
continue;
}
}
dr.Close();
conID.Close();
return var;
}
// a static variable that holds the ID............................
public class IDGen
{
public static string varr;
}
One word of advice: don't try to make this any more difficult than it is, and don't try to outsmart SQL Server. Why don't you just use the database-provided mechanisms that's already in place for this: an IDENTITY column?
I would recommend you use:
an ID INT IDENTITY(1,1) column to get SQL Server to handle the automatic increment of your numeric value
a computed, persisted column to convert that numeric value to the value you need
So try this:
CREATE TABLE dbo.DSR
(ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED,
DsrID AS 'DSR-' + RIGHT('00000000' + CAST(ID AS VARCHAR(8)), 8) PERSISTED,
.... your other columns here....
)
Now, every time you insert a row into DSR without specifying values for ID or DsrID:
INSERT INTO dbo.DSR(Col1, Col2, ..., ColN)
VALUES (Val1, Val2, ....., ValN)
then SQL Server will automatically and safely increase your ID value, and DsrID will contain values like DSR-0000001, DSR-0000002,...... and so on - automatically, safely, reliably, no duplicates.
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.