Hey, I am using iBATIS with SQL Server Compact Edition 3.5 and try to do a subselect
INSERT INTO FORMINSTANCE (ID, ID_FORM)
SELECT #ID#, f.ID
FROM FORM f
WHERE ID_PROCESS='10804'
When I commit the transaction I get an SqlCeException (SSCE_M_QP_PARAMETERNOTALLOWED).
That the Symbol '#' is on the wrong place. I think this is the #ID# which is unpredicted in SELECT. #ID# is not the name of the column, it's the value that should be inserted into FORMINSTANCE How can i fix this?
ty
If the # part of the column nameā¦
INSERT INTO FORMINSTANCE (ID, ID_FORM)
SELECT [#ID#], f.ID
FROM FORM f
WHERE ID_PROCESS='10804'
If for some odd reason you wanted a dynamic column to be selected at position #1 (not that I really think that this is what you're up to, but anyway), you could get away with:
INSERT INTO FORMINSTANCE (ID, ID_FORM)
SELECT
CASE
WHEN #ID = 'foo' THEN foo
WHEN #ID = 'bar' THEN bar
ELSE NULL
END,
f.ID
FROM
FORM f
WHERE
ID_PROCESS='10804'
I don't think you can if #ID# isn't in the FORM table (ie, a parameter). Even if #ID# was in the standard parameter format of #ID, SQL Server CE doesn't support named parameters in that location.
Related
I have a component that retrieves data from database based on the keys provided.
However I want my java application to get all the data for all keys in a single database hit to fasten up things.
I can use 'in' clause when I have only one key.
While working on more than one key I can use below query in oracle
SELECT * FROM <table_name>
where (value_type,CODE1) IN (('I','COMM'),('I','CORE'));
which is similar to writing
SELECT * FROM <table_name>
where value_type = 1 and CODE1 = 'COMM'
and
SELECT * FROM <table_name>
where value_type = 1 and CODE1 = 'CORE'
together
However, this concept of using 'in' clause as above is giving below error in 'SQL server'
ERROR:An expression of non-boolean type specified in a context where a condition is expected, near ','.
Please let know if their is any way to achieve the same in SQL server.
This syntax doesn't exist in SQL Server. Use a combination of And and Or.
SELECT *
FROM <table_name>
WHERE
(value_type = 1 and CODE1 = 'COMM')
OR (value_type = 1 and CODE1 = 'CORE')
(In this case, you could make it shorter, because value_type is compared to the same value in both combinations. I just wanted to show the pattern that works like IN in oracle with multiple fields.)
When using IN with a subquery, you need to rephrase it like this:
Oracle:
SELECT *
FROM foo
WHERE
(value_type, CODE1) IN (
SELECT type, code
FROM bar
WHERE <some conditions>)
SQL Server:
SELECT *
FROM foo
WHERE
EXISTS (
SELECT *
FROM bar
WHERE <some conditions>
AND foo.type_code = bar.type
AND foo.CODE1 = bar.code)
There are other ways to do it, depending on the case, like inner joins and the like.
If you have under 1000 tuples you want to check against and you're using SQL Server 2008+, you can use a table values constructor, and perform a join against it. You can only specify up to 1000 rows in a table values constructor, hence the 1000 tuple limitation. Here's how it would look in your situation:
SELECT <table_name>.* FROM <table_name>
JOIN ( VALUES
('I', 'COMM'),
('I', 'CORE')
) AS MyTable(a, b) ON a = value_type AND b = CODE1;
This is only a good idea if your list of values is going to be unique, otherwise you'll get duplicate values. I'm not sure how the performance of this compares to using many ANDs and ORs, but the SQL query is at least much cleaner to look at, in my opinion.
You can also write this to use EXIST instead of JOIN. That may have different performance characteristics and it will avoid the problem of producing duplicate results if your values aren't unique. It may be worth trying both EXIST and JOIN on your use case to see what's a better fit. Here's how EXIST would look,
SELECT * FROM <table_name>
WHERE EXISTS (
SELECT 1
FROM (
VALUES
('I', 'COMM'),
('I', 'CORE')
) AS MyTable(a, b)
WHERE a = value_type AND b = CODE1
);
In conclusion, I think the best choice is to create a temporary table and query against that. But sometimes that's not possible, e.g. your user lacks the permission to create temporary tables, and then using a table values constructor may be your best choice. Use EXIST or JOIN, depending on which gives you better performance on your database.
Normally you can not do it, but can use the following technique.
SELECT * FROM <table_name>
where (value_type+'/'+CODE1) IN (('I'+'/'+'COMM'),('I'+'/'+'CORE'));
A better solution is to avoid hardcoding your values and put then in a temporary or persistent table:
CREATE TABLE #t (ValueType VARCHAR(16), Code VARCHAR(16))
INSERT INTO #t VALUES ('I','COMM'),('I','CORE')
SELECT DT. *
FROM <table_name> DT
JOIN #t T ON T.ValueType = DT.ValueType AND T.Code = DT.Code
Thus, you avoid storing data in your code (persistent table version) and allow to easily modify the filters (without changing the code).
I think you can try this, combine and and or at the same time.
SELECT
*
FROM
<table_name>
WHERE
value_type = 1
AND (CODE1 = 'COMM' OR CODE1 = 'CORE')
What you can do is 'join' the columns as a string, and pass your values also combined as strings.
where (cast(column1 as text) ||','|| cast(column2 as text)) in (?1)
The other way is to do multiple ands and ors.
I had a similar problem in MS SQL, but a little different. Maybe it will help somebody in futere, in my case i found this solution (not full code, just example):
SELECT Table1.Campaign
,Table1.Coupon
FROM [CRM].[dbo].[Coupons] AS Table1
INNER JOIN [CRM].[dbo].[Coupons] AS Table2 ON Table1.Campaign = Table2.Campaign AND Table1.Coupon = Table2.Coupon
WHERE Table1.Coupon IN ('0000000001', '0000000002') AND Table2.Campaign IN ('XXX000000001', 'XYX000000001')
Of cource on Coupon and Campaign in table i have index for fast search.
Compute it in MS Sql
SELECT * FROM <table_name>
where value_type + '|' + CODE1 IN ('I|COMM', 'I|CORE');
Microsoft SQL Server 2008
I have two tables. One has a column in it with data that is _ delimited
example:
Y_21_CA
<BR>
such that:
Yes/No_Age_State
I need to parse the data in this column out and insert it into another table that has individual columns for each value. Let's say Table A contains one column like the example above but Table B contains three columns, YesOrNo, Age, usState.
What's the easiest way to do this? I've tried doing something like:
UPDATE TableA
SET YesOrNo = SUBSTRING (TableB.Column1, 1, 1)
but SUBSTRING only takes an expression. I really just need some guidance here, I've been banging my head against the wall trying to figure this out since I'm not much of a SQL guru. I can figure out the syntax no problem but maybe I'm not aware of some methods that exist. Thanks
A generic solution, using Charindex of '_' without hardcoding it
declare #s varchar(10) = 'Y_21_CA'
SELECT LEFT(#s, CHARINDEX('_',#s,1)-1) YN,
SUBSTRING(#s, CHARINDEX('_',#s,1)+1,
CHARINDEX('_',#s,CHARINDEX('_',#s,1)) ) Age,
RIGHT(#s, CHARINDEX('_',reverse(#s),1)-1) State
--Results
Y 21 CA
In case you expect to use this logic often in other queries, you could make the SELECT statement an inline TVF. Then you would be able to use it with your update like this:
UPDATE b
SET YesOrNo = x.YN,
Age = x.Age,
State = x.State
FROM TableB b
INNER JOIN TableA a ON b.ID = a.ID
CROSS APPLY ThreeColumnSplit(a.S) x;
Here's a "live" demo at SQL Fiddle. (Please never mind its using the SQL Server 2012 engine. That's only because the Fiddle's 2008 instance appears to be down at the moment and can't be used. There's nothing SQL Server 2012-specific in the script.)
You should be able to use the following, I think you want an INSERT instead of UPDATE.
The SELECT statement to get the data is:
select substring(yourCol, 1, 1) YesOrNo,
substring(yourcol, 3, len(yourcol)-5) Age,
right(yourCol, 2) usState
from tableA;
See SQL Fiddle with Demo
Then the INSERT statement is:
insert into tableB (YesOrNo, Age, usState)
select substring(yourCol, 1, 1) YesOrNo,
substring(yourcol, 3, len(yourcol)-5) Age,
right(yourCol, 2) usState
from tableA;
See SQL Fiddle with Demo
Note: This assumes that the YesOrNo column will always only have one character and that the usState will always have 2 characters.
I Can't run this query with SQLite
if 0<(select COUNT(*) from Repetition where (Word='behnam' and Topic='mine'))
begin
update Repetition set Counts=1+ (select Counts from Repetition where (Word='behnam' and Topic='mine'))
end
else
begin
insert Repetition(Word,Topic,Counts)values('behnam','mine',1)
end
It says "Syntax error near IF"
How can I solve the problem
SQLite does not have an IF statement (see the list of supported queries)
Insetad, check out out ERIC B's suggestion on another thread. You're effectively looking at doing an UPSERT (UPdate if the record exists, INSERT if not). Eric B. has a good example of how to do this in SQLite syntax utilizing the "INSERT OR REPLACE" functionality in SQLite. Basically, you'd do something like:
INSERT OR REPLACE INTO Repetition (Word, Topic, Counts)
VALUES ( 'behnam', 'mine',
coalesce((select Counts + 1 from Repetition
where Word = 'behnam', AND Topic = 'mine)
,1)
)
Another approach is to INSERT ... SELECT ... WHERE ... EXISTS [or not] (SELECT ...);
I do this sort of thing all the time, and I use jklemmack's suggestion as well. And I do it for other purposes too, such as doing JOINs in UPDATEs (which SQLite3 does not support).
For example:
CREATE TABLE t(id INTEGER PRIMARY KEY, c1 TEXT NOT NULL UNIQUE, c2 TEXT);
CREATE TABLE r(c1 TEXT NOT NULL UNIQUE, c2 TEXT);
INSERT OR REPLACE INTO t (id, c1, c2)
SELECT t.id, coalesce(r.c1, t.c1), coalesce(r.c2, t.c2)
FROM r LEFT OUTER JOIN t ON r.c1 = t.c1
WHERE r.c2 = #param;
The WHERE there has the condition that you'd have in your IF. The JOIN in the SELECT provides the JOIN that SQLite3 doesn't support in UPDATE. The INSERT OR REPLACE and the use of t.id (which can be NULL if the row doesn't exist in t) together provide the THEN and ELSE bodies.
You can apply this over and over. If you'd have three statements (that cannot somehow be merged into one) in the THEN part of the IF you'd need to have three statements with the IF condition in their WHEREs.
This is called an UPSERT (i.e. UPdate or inSERT). It has its forms in almost every type of database. Look at this question for the SQLite version: SQLite - UPSERT *not* INSERT or REPLACE
One way that I've found is based on SQL WHERE clause true/false statement:
SELECT * FROM SOME_TABLE
WHERE
(
SELECT SINGLE_COLUMN_NAME FROM SOME_OTHER_TABLE
WHERE
SOME_COLUMN = 'some value' and
SOME_OTHER_COLUMN = 'some other value'
)
This actually means execute some QUERIES if some other QUERY returns 'any' result.
I have a carsale project. It completely works on localhost. I have a "AddCar.aspx" page that inserts a car record with car's features. Car features are selected with checkboxes. If i don't check any checkbox, there is no problem. But if i check one of feature checkboxes, my page gives an error like this:
"Subqueries are not allowed in this
context. Only scalar expressions are
allowed."
And my code is like that:
foreach (DataListItem item in Security1.Items) {
CheckBox CheckBox1 = (CheckBox)item.FindControl("CheckBox1");
if (CheckBox1.Checked) {
HiddenField h = (HiddenField)item.FindControl("FeaID");
string add = "Insert into Carfeature (RecID,FeatureID) values ((select Max(RecID) from record),#FeatureID)";
cmd[k] = new SqlCommand();
cmd[k].CommandType = CommandType.Text;
cmd[k].Parameters.Add("#FeatureID", SqlDbType.Int).Value = h.Value;
cmd[k].CommandText = add;
k++;
}
}
Is there any solution?
Two things, first of all, try this SQL:
Insert into Carfeature (RecID,FeatureID)
select Max(RecID), #FeatureID from record;
Secondly, the Max(RecId) is problematic if you have multiple threads doing this. Are you aware that you can get the last inserted identity? Isn't that what you want to do here? If you've just inserted a record into the record table in the previous step
select SCOPE_IDENTITY() as RecID;
will give you the correct RecID in a thread safe manner.
Change your SQL to this:
Insert into Carfeature (RecID,FeatureID)
select Max(RecID), #FeatureID from record
I think you could just re-format your sql and do it this way:
Insert into Carfeature (RecID,FeatureID) select Max(RecID), #FeatureId from record
This is most likely due to concurrency control. A way I'd recommend doing this on SQL Server 2005 is to change your sql statement to the following using CTE's(http://msdn.microsoft.com/en-us/library/ms190766.aspx):
with MaxId as
(
select Max(RecID)
from record
)
insert into Carfeature (RecID,FeatureID)
select #MaxID, #FeatureID
from MaxId
Friends, you all answered true, thanks a lot.
I changed my code like that and it worked:
Insert into Carfeature (RecID,FeatureID) select Max(RecID), #FeatureID from record
But I don't know how to set accepted answer, because all of answers are true :)
I'm trying to verify a simple 1 field table to determine if a record exists before inserting a duplicate.
if not exists (select * from url where url = ...)
insert into url...
Can someone Help?
Your code example will run in the full version of SQL, or you could rearrange to the following:
insert into url
select 'myvalue'
where not exists (select * from url where url = 'myvalue')
Just reverse it and add the condition as a where clause predicate
Insert Into Table ....
Where Not Exists
(Select * From table where ...)
... But your basic problem sounds like it might be better solved by putting a alternate key (unique) constraint on the insert table, referencing the url column (I assume Sql CE does Referential Integrity (RI) constraints?)
You might want to read this thread. performing-insert-or-update-upsert-on-sql-server-compact-edition
In a nutshell a sqlce specific solution (using SqlCeResultSet) will provide the maximum performance.
Use an Outer Join
Insert into X(...)
select blah, blah, blah
from
table t left outer join
X on t.id=x.id
where
x.id is null
Granted, this is way past the posting date, but since I've not seen this answered elsewhere in my quick Google search, I thought I'd share how I solved this with SQL CE so others searching might find an answer.
-- Update existing record's value
UPDATE myTable SET myValue = 'Hello World' WHERE keyField = 'MyKey';
-- Insert new record if existing record doesn't exist`
INSERT INTO myTable (keyField, myValue)
SELECT I.keyField, I.myValue
FROM (
SELECT 'Hello World' AS myValue, 'MyKey' AS keyField
) I
LEFT JOIN myTable T ON I.keyField = T.keyField
WHERE T.keyField IS NULL;
You are on the right path with IF NOT EXISTS. It is better to use IF NOT EXISTS() or IF EXISTS() than a Sub Query because SQL Server will stop scanning rows in the table when it finds the first instance that matches the EXISTS() condition your looking for. With a Sub Query written in the examples above it will scan the whole table.
A Classic example is the Insert or Update aka the SAVE.
IF EXISTS(SELECT * FROM Table_A WHERE Column_1 = #Parameter)
BEGIN
--Update Statement here.
END
ELSE
BEGIN
--Insert Statement here.
END
What about something like this:
UPDATE Table1 SET (...) WHERE Column1='SomeValue'
IF ##ROWCOUNT=0
INSERT INTO Table1 VALUES (...)
Source