Today I encountered problem that causes difficulty for me to solve it.
In application I want to display records in aphabetical order thus in SQL statement I'am using ORDER BY, But it looks like CAPITAL letters are before lowercase letters so record starting with Z is before a.
This is example of my sql statement
SELECT * FROM myTable WHERE id= 5 ORDER BY name
Do you have any ideas ? Can I sort data in DataTable object after retreiving it from database ? or can it be accomplished by more complex sql statement?
Any ideas will be appreciated
You can modify your SQL query in such a way that all capitals are transformed to lower before ordering
SELECT * FROM myTable WHERE id = 5 ORDER BY LOWER(name)
The rules for comparing text values is the collation; there are many many collations available in SQL Server, and most have both case-sensitive and case-insensitive options.
If you don't want to change the collation (in particular, if this applies only to specific cases), you can also use functions like LOWER / UPPER, but this cannot make efficient use of indexes. A hybrid approach is to store redundant information: store the original data in one column, and the standardized data (perhaps all lower-case-invariant) in a second column. Then you can index the two separately (as you need), and operate on either the original or standardized data. You would normally only display the original data, though. Persisted+calculated+indexed columns might work well here, as then it is impossible to get inconsistent data (the server is in charge of the calculated column).
Try
SELECT * FROM myTable WHERE id= 5 ORDER BY LOWER(name)
OR
SELECT * FROM myTable WHERE id= 5 ORDER BY LCASE(name)
depending on which database you are using
You can perform ordering by providing case in SQL. Just do this:
SELECT * FROM myTable WHERE id= 5 ORDER BY UPPER(name)
OR
SELECT * FROM myTable WHERE id= 5 ORDER BY UCASE(name)
Ordering will be done on upper case name while you result will be same as present in table.
Try this...
SELECT * FROM myTable WHERE id= 5 ORDER BY name COLLATE Latin1_General_100_CI_AS
Related
I have to remove the particular value from the sentence which is stored in SQL database. Sentence will look like this:
1 Payments:ihj - CHENNAI-HIRE:54005-TN69AZ54008,4021-TN69AZ54005
2 Payments:ihj - CHENNAI-HIRE:54004-TN69AZ54008,4021-TN69AZ54005,54005-TN69AZ54008
In above sentence 54004 is the number which I will pass as parameter to SQL. This is the number which I want to remove from this line but same number is present in this line as TN69AZ54005. This number should not be disturbed, and in another payment we have same amount in another place. Can anyone help on this?
I tried with this sql query
declare #text int=4019
select SUBSTRING(notes,CHARINDEX(cast(#text as varchar),notes),
len(notes)-CHARINDEX(',',notes)+1)
from Accounts.TransactionNotes
where TransactionID=1978
If I use this query it will affect including this line TN69AZ54005
I can see that you've included a C# tag into your question. Then probably the easiest way is just to select all necessary rows using your app, then iterate through them and change the strings to your needs (using eg. PHP preg_replace() equivalent) and update the SQL rows.
I believe that is the easiest way, not really SQL solution but still...
update <table> set notes = replace(notes, 'HIRE:'+ str(<inputparam>),'HIRE:') where transactionid=<transactionid>
update <table> set notes = replace(notes, ','+ str(<inputparam>),',') where transactionid=<transactionid>
You will need to find something to prefix your inputpram value, like in above example I am using "HIRE:" or a comma.
Another way could be to use REGEXP to find the whole word, then one one query would suffice. But I haven't tried it.
The problem here is not the query but the person who designed the
database.
I`m not sure is it this what you want but I will past my code. :)
-- for test create #temp
SELECT
A.DATA
INTO #Temp
FROM
(
SELECT 'Payments:ihj - CHENNAI-HIRE:54005-TN69AZ54008,4021-TN69AZ54005' AS DATA
UNION
SELECT 'Payments:ihj - CHENNAI-HIRE:54004-TN69AZ54008,4021-TN69AZ54005,54005-TN69AZ54008' AS DATA
) AS A
GO
-- this you want?
UPDATE #Temp
SET DATA = REPLACE(DATA,'54004','')
GO
-- select changed data
SELECT * FROM #Temp
When my query is:
select * from table_name where name='jim'
everything is fine.
But when my query is:
select * from table where ='a statement with 2 and more word'
For example this query:
select columns from table where ='jim carrey'
The query just considers 'jim'. In other words, the query just considers the first word and does not consider whatever comes after that.
SQL does not work like that. If you take the following three queries:
select * from users where name = 'Frank Jones'
select * from users where name = 'Frank'
select * from users where name like 'Frank%'
If I run these on my SQL server database (after changing back to our real data structure) I will get 1 response to the first , the person who is actually named "Frank Jones'. I will not get 'Frank Jones III'
Since both first and last names are in the name columns if I run the second query, I will get no results.
If I run the third query I will get everyone whose first name if Frank but will not get "Jason Franks' because I only have a wildcard at the end of the phrase I am searching for. If I wanted everyone who had and portion of Frank in their name I would write this query:
select * from users where name like '%Frank%'
These are standard rules on what the various where clauses mean that apply to every database I have ever seen (although some might have a differnt wildcard symbol).
You don't say what platform you are using which makes answering your question harder but I will give an answer that will be close.
You need to parse the first work in the string. So
SELECT aColumn
FROM aTable
WHERE name = LEFT('Jim Carrey', CHARINDEX('Jim Carrey',' '))
Would be an example in sql server
The name of these functions changes for each platform.
Is it possible to create a SQL select max(id) as a variable inside a query?
This doesn't work:
command.CommandText = "INSERT INTO ordreid (ordrenr,ordreid) SELECT #ordrenr, #ordreid";
command.Parameters.AddWithValue("#ordrenr", nyordre);
command.Parameters.AddWithValue("#ordreid", ("MAX(ordreid)+1 FROM ordreid"));
command.ExecuteScalar();
Here is a photo of what I'd like to do. 5 customers have added items to their orders. Customer 1 has 3 items, customer 2 has 4 items, customer 3 has 1 item, and so on...
This way I have 1 ordreid even through the order could consist of 30 items.
Query parameters cannot include SQL verbatim.
This is how such prepared statements prevent SQL Injection as they are not directly inserted. Rather only the corresponding data is used in the query - in this case that is the string that contains SQL, and results in invalid SQL syntax.
The SQL text then needs to look similar to the following, although this probably does not do what is desired. (Asking how to do the higher level task will lead to actually useful queries/approaches.)
#"INSERT INTO ordreid (ordrenr, ordreid)
SELECT #ordrenr, MAX(ordreid)+1
FROM ordreid"
command.Parameters.AddWithValue("#ordreid", ("MAX(ordreid)+1 FROM ordreid"));
The method name AddWithValue hints at the reason why this won't work: Parameters contain data, that is: values. They cannot represent a part of a SQL statement.
Your intention appears to be that #ordreid should be replaced with that piece of SQL. If this is so, then there's no reason to even have a parameter. Simply perform the substitution manually and change the CommandText:
command.CommandText = #"INSERT INTO ordreid (ordrenr, ordreid)
VALUES (#ordrenr, (SELECT MAX(ordreid)+1 FROM ordreid));";
Note that I changed four things (apart from spreading the command text across two lines, for legibility's sake, using C#'s #"…" string syntax). Only the first two points are crucial:
I moved the MAX(…) SQL directly into your CommandText. This makes the (invalid) #ordreid parameter obsolete.
To determine the value of MAX(ordreid) FROM ordreid, you need a sub-query; thus the added SELECT before MAX. Otherwise, the syntax wouldn't be valid.
I replaced your SELECT with a VALUES table value constructor. (Otherwise, because of the previous point, we'd have two SELECTs very close to each other, which would look somewhat confusing.)
I added a ; at the end of your query. Current versions of SQL Server don't yet require such a statement terminator, but Microsoft has hinted that they might become compulsory in future versions of T-SQL. I therefore believe that it's a good habit to get into now.
That all being said, you should probably turn the ordreid column into an IDENTITY column and let SQL Server choose the value to be inserted (making the SELECT MAX(…) business obsolete). Otherwise, if two processes or threads execute the same INSERT command at the same time, you might end up with several rows having the same value for ordreid.
I'm using SQL Server 2000, and given a a set of data (with unique ID's), I want to figure out the diffs with rows in the database, matching on the unique IDs. I'm also trying to keep it as flexible as possible.
I can use C#/VB in the front end to take the parameters, or even return things. Maybe passing in XML and getting XML in return?
For example, I want a function that calls:
// returns the columns that are different
func( A, B, C ) {
}
Any ideas?
There's a cool trick you can use with UNION:
SELECT MAX(tbl) AS TABLE_NAME, unique_key
FROM (
SELECT 'table1' AS tbl, unique_key
FROM table1
UNION ALL
SELECT 'table2' AS tbl, unique_key
FROM table2
) AS X GROUP BY unique_key
HAVING COUNT(*) = 1
This will show where one side or the other has rows which the other doesn't have.
This can be expanded to do more, obviously.
Alternatively, you can do an INNER JOIN (matches on keys where data is different), LEFT JOIN (key missing on one side) and RIGHT JOIN (key missing on the other) and UNION them all together.
I actually have a utility SP (it uses one or the other method depending on what options you need) which will compare any two tables and has options for setting which columns are considered the part of keys, which columns to ignore, restrict each side to a subset, etc. It even has an option to write the differences to a table.
I'd go with an existing "data diff" tool like
Red-Gate SQL Data Compare
ApexSQL Data Diff
Marc
Yeah agree with Marc, a specialized tool works best, something like Volpet Table Diff for SQL Server
I am a PHP/MySQL developer, slowly venturing into the realm of C#/SQL Server and I am having a problem in C# when it comes to reading an SQL Server query that joins two tables.
Given the two tables:
TableA:
int:id
VARCHAR(50):name
int:b_id
TableB:
int:id
VARCHAR(50):name
And given the query
SELECT * FROM TableA,TableB WHERE TableA.b_id = TableB.id;
Now in C# I normally read query data in the following fashion:
SqlDataReader data_reader= sql_command.ExecuteReader();
data_reader["Field"];
Except in this case I need to differentiate from TableA's name column, and TableB's name column.
In PHP I would simply ask for the field "TableA.name" or "TableB.name" accordingly but when I try something like
data_reader["TableB.name"];
in C#, my code errors out.
How can fix this? And how can I read a query on multiple tables in C#?
The result set only sees the returned data/column names, not the underlying table. Change your query to something like
SELECT TableA.Name as Name_TA, TableB.Name as Name_TB from ...
Then you can refer to the fields like this:
data_reader["Name_TA"];
To those posting that it is wrong to use "SELECT *", I strongly disagree with you. There are many real world cases where a SELECT * is necessary. Your absolute statements about its "wrong" use may be leading someone astray from what is a legitimate solution.
The problem here does not lie with the use of SELECT *, but with a constraint in ADO.NET.
As the OP points out, in PHP you can index a data row via the "TABLE.COLUMN" syntax, which is also how raw SQL handles column name conflicts:
SELECT table1.ID, table2.ID FROM table1, table;
Why DataReader is not implemented this way I do not know...
That said, a solution to be used could build your SQL statement dynamically by:
querying the schema of the tables you're selecting from
build your SELECT clause by iterating through the column names in the schema
In this way you could build a query like the following without having to know what columns currently exist in the schema for the tables you're selecting from
SELECT TableA.Name as Name_TA, TableB.Name as Name_TB from ...
You could try reading the values by index (a number) rather than by key.
name = data_reader[4];
You will have to experiment to see how the numbers correspond.
Welcome to the real world. In the real world, we don't use "SELECT *". Specify which columns you want, from which tables, and with which alias, if required.
Although it is better to use a column list to remove duplicate columns, if for any reason you want *****, then just use
rdr.item("duplicate_column_name")
This will return the first column value, since the inner join will have the same values in both identical columns, so this will accomplish the task.
Ideally, you should never have duplicate column names, across a database schema. So if you can rename your schema to not have conflicting names.
That rule is for this very situation. Once you've done your join, it is just a new recordset, and generally the table names do go with it.