error converting varchar to numeric : SQL Server 2008 - sql-server

I have this SQL statement but it return : "error converting varchar to numeric"
ADOTailles.SQL.Text := 'INSERT INTO tailles (numOF, taille, quantite, prixVente) VALUES(''' + numOF.Text + ''',''' + C.Caption + ''',''' + Q.Text + ''',''' + P.Text + ''')';
ADOTailles.ExecSQL
The numeric field is prixVente;
I used this but still the same error:
ADOTailles.SQL.Text := 'INSERT INTO tailles (numOF, taille, quantite, prixVente) VALUES(''' + numOF.Text + ''',''' + C.Caption + ''',''' + Q.Text + ''',CAST(''' + P.Text + ''' AS numeric(5, 2)))');
ADOTailles.ExecSQL
NOTE: If I put an INTEGER there is no error
The full code is:
var
I: Int8;
C: TCheckBox;
Q, P: TEdit;
for I := 1 to 16 do Begin
C := FindComponent('T' + IntToStr(I)) as TCheckBox;
Q := FindComponent('Q' + IntToStr(I)) as TEdit;
P := FindComponent('P' + IntToStr(I)) as TEdit;
if C.Checked = True then begin
ADOTailles.SQL.Text := 'INSERT INTO tailles (numOF, taille, quantite, prixVente) VALUES(''' + numOF.Text + ''',''' + C.Caption + ''',''' + Q.Text + ''',''' + P.Text + ''')';
ADOTailles.ExecSQL
end;
End;
there is no SQL injection because I use this code:
StringReplace(aricleFilter.Text, '''', '', [rfReplaceAll]);

Don't create a SQL query by appending text; use parameters.
Or you'll fall into the Bobby Tables SQL injection trap.
It makes it way easier to get rid of these errors too.

Maybe your string contains not numeric symbols or incorrect decimal separator (for example "," instead of ".").

You are putting the value for the price between quotes
... ''',''' + P.Text + ''')';
This is what causes SQLServer to try a conversion from varchar to a number. To prevent that, you will have to leave of the quotes:
... ''',' + P.Text + ')';
and make sure that P.Text contains the decimal and thousands separators that SQL Server expects. Preferably only the decimal separator. You can always do the conversion yourself using StrToFloat or StrToFloatDef with P.Text as the input and then reformat that for SQLServer.
From what I can remember, SQL Server expects the US separators in SQL statements, which means you need to use a point as the decimal separator.

Related

Set empty value of column before create new one in case

I have sp like this:
DECLARE #comando as varchar(5000)
set #comando = 'DTEXEC /FILE \"" /de "pass" /CHECKPOINTING OFF /REPORTING EW'
select #comando = #comando + ' /SET "\"\Package.Variables[' + Replace(str_NombreVariable,'User::','') + '].Value\"";'
+ str_ValorVariable +
CASE WHEN str_NombreVariable LIKE '%v_sRutaArchivo%' THEN #archivoCargado + '.csv\""' ELSE '' END + ''
from [Catalogo].[catVariablesEtl] where IdPaquete = 42
That I want to do is to do another case:
CASE WHEN str_NombreVariable LIKE '%v_sCadenaConexion%' THEN '"\"'+ str_ValorVariable ELSE '' END +
But I want to drop result of v_sCadenaConexion value after create this new one with case. How can I do that? Because If I use case with query it just duplicate existing value .
I want something like if str_NombreVariable exist get that value and create new one with my case sentence. How can I achieve that?
Problem:
Package.Variables[v_sCadenaConexion].Value\"";Data Source=0.0.0.0\BA;User ID=BAS;Password=000;Initial Catalog=BOS;Persist Security Info=True;Initial Catalog=SS;Persist Security Info=True;
"\"Data Source=0.0.0.0\BA;User ID=BAS;Password=000;Initial Catalog=BOS;Persist Security Info=True;Initial Catalog=SS;Persist Security Info=True;
As you can see it duplicate value. So I want to dismiss first one and keep second one(CASE one)
Not sure if this is what you mean or not...
DECLARE #comando as varchar(5000)
set #comando = 'DTEXEC /FILE \"" /de "pass" /CHECKPOINTING OFF /REPORTING EW'
select #comando = #comando + ' /SET "\"\Package.Variables[' + Replace(str_NombreVariable,'User::','') + '].Value\"";'
+ CASE WHEN str_NombreVariable LIKE '%v_sCadenaConexion%'
THEN '"\"'+ str_ValorVariable
ELSE str_ValorVariable +
CASE WHEN str_NombreVariable LIKE '%v_sRutaArchivo%'
THEN #archivoCargado + '.csv\""'
ELSE ''
END
END + ''
from [Catalogo].[catVariablesEtl] where IdPaquete = 42

String conversion in sql server

In Sql server, I want to convert a string 'EN,ES,FR'to ISNULL('EN','') + ISNULL('FR','') + ISNULL('ES',''). What is the easiest way to do that. Thanks in advance.
Is this what you mean?
declare #list nvarchar(20)
set #list = 'EN,FR,ES'
print 'ISNULL(''' + replace(#list, ',', ''','''') + ISNULL(''') + ''','''')'
Output is
ISNULL('EN','') + ISNULL('FR','') + ISNULL('ES','')
...or have I got completely the wrong end of the stick?!

My R code is not fetching data from SQL Server

While the normal Select statements used on R are fetching the data, I am not able to fetch the data using SQL on the following query:
The SQL part is working on SQL Server 2008. Also, I am using RStudio
Any suggestions what is wrong here?
qf<-sqlQuery(mycon,"USE MDM_STAT
+ DECLARE #RUNMONTH INT;
+ DECLARE #RUNYEAR INT;
+ DECLARE #PERIOD INT;
+ DECLARE #FISCALRUNYEAR INT;
+ DECLARE #FISCALRUNYEAR_BEGIN INT;
+ SET #RUNMONTH=MONTH(GETDATE());
+ SET #RUNYEAR=YEAR(GETDATE());
+ SET #PERIOD=
+ CASE
+ WHEN #RUNMONTH>3 THEN (#RUNMONTH-3)
+ ELSE 9+#RUNMONTH
+ END
+ ;
+ SET #FISCALRUNYEAR=
+ CASE
+ WHEN #RUNMONTH>3 THEN #RUNYEAR
+ ELSE #RUNYEAR-1
+ END
+ ;
+ SET #FISCALRUNYEAR_BEGIN=
+ CASE
+ WHEN #PERIOD=12 THEN #FISCALRUNYEAR
+ ELSE #FISCALRUNYEAR-1
+ END
+ ;
+
+ select * from dbo.TEMP_CUST_OPERATING_PROFIT OP
+ where OP.Sales_Year=#FISCALRUNYEAR
+ AND OP.PERIOD<=#PERIOD
+ UNION
+ select * from dbo.TEMP_CUST_OPERATING_PROFIT OP
+ where OP.Sales_Year=#FISCALRUNYEAR_BEGIN
+ AND OP.PERIOD>#PERIOD")
I suggest you to follow the following steps:
1) You should make sure the the connection string is set correctly for establishing the correct connection with the database.
a quite good explanation appears here: short youtube tutorial
2) in R write:
library(RODBC)
channel = odbcConnect("The_database_name_your_are_connecting_to")
...
sqlQuery(channel ,"your query here")
close(channel)
I suggest you to start with the simplest query and after you made sure it worked,
go with a more complex query
hope it would work for you, good luck!

Delphi table Join

I’ve been tasked with patching a Delphi software to work with a new database(mssql) structure.
In the previous database(mssql), all the columns being read were in the same table.
In the new version the file_name and class_name are in a different table as the quantity values.
I believe I can fix this by writing a Join for these two database tables.
Issue is, I’m not familiar with Delphi!
The current code is below.
How do I get these two databases to join into one?
dataTable=style001
dataTable1=style
THANKS!!!
dataTable.Active := True;
datatable.Open;
dataTable1.Active := True;
datatable1.Open;
while not datatable1.Eof do
begin
Application.ProcessMessages;
file_name := trim(datatable1.FieldByName('code').asString) + '.jpg';
class_name := trim(datatable1.FieldByName('category').asString);
if not FileExists(picfolder + file_name) then
begin
dataTable1.next;
continue;
end;
instock := datatable.FieldByName('onhand').asString;
TryStrToInt(instock, instock_num);
quantity := datatable.FieldByName('onorder').asString;
TryStrToInt(quantity, num);
num := instock_num - num;
is_active := ( num > 10 );
for i := 0 to file_count-1 do
begin
if is_active = active_class[file_class[i]] then
if SameText(files[i],file_name) then
begin // use TStringList instead
if SameText(class_name, classes[file_class[i]]) then // same class
begin
file_ok[i] := true;
class_ok[file_class[i]] := true;
end;
break;
end;
end;
if class_name <> '' then class_name := class_name + '\';
dest := picfolder + active_path[is_active] + class_name;
deldest := picfolder + active_path[not is_active] + class_name;
{$I-}
if FileExists(deldest + file_name) then
DeleteFile(PChar(deldest + file_name ));
if not FileExists(dest + file_name) then
begin
ForceDirectories(dest);
CopyFile(PChar(picfolder + file_name ), PChar(dest + file_name ), true );
end;
dataTable1.next;
end;
for i := 0 to file_count-1 do
if not file_ok[i] then
begin // delete wrong file if empty
// ShowMessage('problem: ' + picfolder + active_path[active_class[file_class[i]]] + classes[file_class[i]] + '\' + files[i]);
DeleteFile(picfolder + active_path[active_class[file_class[i]]] + classes[file_class[i]] + '\' + files[i]);
end;
for i := 0 to class_count-1 do
if not class_ok[i] then
begin // delete old class if empty
// ShowMessage('problem: ' + picfolder + active_path[active_class[i]] + classes[i] + '\' );
RemoveDir(picfolder + active_path[active_class[i]] + classes[i] + '\' );
end;
beep;
dataTable.Active := False;
dataTable1.Active := False;
The JOIN is inside the SQL request, not the consuming loop code you are showing here.
You have to use a TQuery instead of two TTable, and write a SQL select for joining the two tables.
You have to modify the SQL request, add the two tables in the FROM clause of the SELECT, and a JOINture in the WHERE clause. See this article about JOIN.
Use a TDataSource and connect its DataSet property to one of the tables. Then set the MasterSource property of the other table to that datasource. Click on the ellipsis button of the MasterFields property and select the connecting fields.
Assuming that the style fields are unique, when you navigate through the first table the second one will follow automatically.

Toad and SQL Server 2005

where a.system_nr =''''5300'''' and
a.external_status_cd = '''''''' and
a.cust_acct_id = b.rel_cust_acct_id and
b.cust_acct_id = c.cust_acct_id and
c.cust_acct_id = d.cust_acct_id and
d.acct_status_cd = ''''OPEN'''' and
d.time_mnth_gen_id =''''' + #BegDate + ''''' and
a.cust_acct_id = e.cust_acct_id and
e.tran_dt >=''''' + #BegDate + ''''' and
e.tran_dt<=''''' + #EndDate + ''''' and
d.portfolio_cd = ''''HEQ'''' and
a.time_mnth_gen_id =''''' + #BegDate + ''''' '')'
Here is the where condition which is already written and I need to make changes.
Can you please tell me why they are using '''''+#begdate'''''? Can i use '+Bedate'?
I mean why they are using ''''' each side?
Try this in SQL Server:
select '''''someval'''''
You notice that item gives:
''someval''
In SQL Server '' will equate to a single quote character, so the above line is
select [open string][single quote][single quote]someval[single quote][single quote][close string]
Without seeing the rest of the SQL, my guesses would be:
for use in dynamic SQL as #BegDate is a variable and you have the statement ending with a single quote
the data contains a bunch of single quotes
You should not be able to just '+BegDate' because it's a variable and stripping the # would cause it to be evaluated as a field.
If you meant to just reduce the number of single quotes, I would imagine the original author put them there for a reason. You can run the query with the original single quotes and again with the reduced single quotes and see if you get the same result set.

Resources