I have phone number field in database. It has already data.
I want to change my phone number format to "XXX-XXX-XXXX"
Current database has no any phone format.
So there may be garbage data. I have already applied validation for new records but now I want to change my existing data also.
Is there any specific way through that I can change my existing data. And make all phone numbers to follow this format.
Please advice.
Create function to remove the non-numeric data and do the formatting
CREATE FUNCTION [UDF_STRIP_NONNUMERIC_DATA](#str VARCHAR(8000))
RETURNS VARCHAR(8000)
AS
BEGIN
WHILE Patindex('%[^0-9]%', #str) > 0
BEGIN
SET #str = Stuff(#str, Patindex('%[^0-9]%', #str), 1, '')
END
RETURN #str
END
You can use STUFF function to inset the - between phone number
Select left(Stuff(Stuff(dbo.[UDF_STRIP_NONNUMERIC_DATA](Phone),4,0,'-'),8,0,'-'),12)
From yourtable
If you are using SQL SERVER 2012+ use can use FORMAT function (thanks to LukStorms, who mentioned it in comment)
SELECT Format(Cast(dbo.[Udf_strip_nonnumeric_data](Phone) AS BIGINT), '###-###-####')
FROM yourtable
To update
Update yourtable
SET phone = left(Stuff(Stuff(dbo.[UDF_STRIP_NONNUMERIC_DATA](Phone),4,0,'-'),8,0,'-'),12)
Demo
declare #str varchar(100)= '9225-123-4567'
select left(Stuff(Stuff(dbo.[UDF_STRIP_NONNUMERIC_DATA](#str),4,0,'-'),8,0,'-'),12)
Result : 922-512-3456
declare #phone varchar(24)
set #phone = '(334)789-4532'
--set #phone = '314789-4532'
--set #phone = '3457894532'
--set #phone = '534-789-4532'
SELECT
LEFT(N,3) + '-' + SUBSTRING(N,4,3) + '-' + RIGHT(N,4)
FROM
(SELECT CAST(CAST((
SELECT SUBSTRING(#phone, Number, 1)
FROM master..spt_values
WHERE Type='p' AND Number <= LEN(#phone) AND
SUBSTRING(#phone, Number, 1) LIKE '[0-9]' FOR XML Path(''))
AS xml) AS varchar(MAX)) as N) as N
Ok, to replace all non-numeric characters, look at this.
Here is a sample script (copied from that link) to show you how it works (You'll need to modify this to fit your table name and column names:
-- Step 1: creates table to use to hold every char in every phone number
if object_id('dbo.tally') is not null drop table dbo.tally
select top 10000 --change to fit max length of phone number
identity(int,1,1) as n
into dbo.tally
from master.dbo.syscolumns sc1,
master.dbo.syscolumns sc2
-- add pk to maximize performance
alter table dbo.tally
add constraint pk_tally_n
primary key clustered (n) with fillfactor = 100
-- Step 2: Create temporary table holding three bad phone numbers
declare #phonetable table
(uniqueid int identity(1,1),
phone_number varchar(500))
insert into #phonetable (phone_number)
select '01234-567-890' union
select '012345 6789ext' union
select 'n/a' union select '...12345.....';
-- Step 3: identify, for every character, whether it is a number or not,
and remove the non-numeric ones
with cte (uniqueid, phone_number, goodchar, badchar) as
( select uniqueid, phone_number,
case when substring(phone_number,N,1) not like '%[^0-9]%'
then substring(phone_number,N,1) end as goodchar,
case when substring(phone_number,N,1) like '%[^0-9]%'
then substring(phone_number,N,1) end as badchar
from #phonetable , Tally
where phone_number like '%[^0-9]%' and N <= len(phone_number) )
select distinct phone_number,
isnull( stuff (
( SELECT '' + goodchar
FROM cte t1
where t1.UniqueID = t2.UniqueID
FOR XML PATH ( '' ) ) , 1 , 0 , '' ) ,'')
as clean_phone_number from cte t2
to display the numbers with formatting, just extract the appropriate pieces and re-concatenate them with the dashes.
Select case len(phone)
When 10 then left(phone, 3) + '-' +
substring(phone, 4,3) + '-' +
substring(phone, 7,4)`
When 7 then left(phone, 3) + '-' +
substring(phone, 4,4)
Else '' end
To create a computed column
Alter table Add Column FormattedPhone as
case len(phone)
When 10 then left(phone, 3) + '-' +
substring(phone, 4,3) + '-' +
substring(phone, 7,4)`
When 7 then left(phone, 3) + '-' +
substring(phone, 4,4)
Else '' end
If you don't mind a UDF
Select [dbo].[udf-Str-Format-Phone]('334)789-4532')
Returns
334-789-4532
The UDF
CREATE FUNCTION [dbo].[udf-Str-Format-Phone] (#S varchar(max))
Returns varchar(25)
AS
Begin
Declare #Return varchar(25)
;with cte0(N) As (Select 1 From (Values(1),(1),(1),(1),(1)) N(N))
, cteN(N) As (Select Top (Len(#S)) Row_Number() over (Order By (Select NULL)) From cte0 N1, cte0 N2)
, cteS(S) As (Select Substring(#S,N,1) From cteN Where Substring(#S, N, 1) LIKE '[0-9]' FOR XML Path(''))
Select #Return = IIf(Len(S)>=10,Stuff(stuff(S,4,0,'-'),8,0,'-'),Stuff(S,4,0,'-')) From cteS
Return #Return
End
-- Syntax : Select [dbo].[udf-Str-Format-Phone]('(334)789-4532') -- Returns 334-789-4532
-- Syntax : Select [dbo].[udf-Str-Format-Phone]('Phone:7894532') -- Returns 789-4532
I want conditionally orderBy my query. All completed tasks (completed 1) should be below uncompleted and ordered by completion time and uncompleted task should be ordered by priority value. I am getting this with following statement:
orderBy = TaskTable.COLUMN_TASK_COMPLETED + " ASC, CASE " +TaskTable.COLUMN_TASK_COMPLETED+" WHEN 0 THEN " +TaskTable.COLUMN_TASK_PRIORITY +" WHEN 1 THEN "+TaskTable.COLUMN_TASK_COMPLETED_TIME + " END DESC";
Now, I want to change it, such way that priority is ordered with ASC attribute and completed_time is ordered with DESC attribute.
I tried:
orderBy = TaskTable.COLUMN_TASK_COMPLETED + " ASC, CASE " +TaskTable.COLUMN_TASK_COMPLETED+" WHEN 0 THEN " +TaskTable.COLUMN_TASK_PRIORITY +" ASK WHEN 1 THEN "+TaskTable.COLUMN_TASK_COMPLETED_TIME + " DESC END";
But it returns error:
Caused by: android.database.sqlite.SQLiteException: near "ASC": syntax error (code 1): , while compiling: SELECT * FROM task_table WHERE (task_name LIKE ? ) ORDER BY task_completed ASC, CASE task_completed WHEN 0 THEN task_priority ASC WHEN 1 THEN task_completed_time DESC END
How to fix it?
The ASC/DESC specifications can be applied only to the top-level expressions used in the ORDER BY clause.
When you have a numeric column, you can simply negate its values, i.e., sort not by X but by -X.
I have an SQL Query for each of my 2 Gridview elements. One is getting all the transactions by branch and transaction date:
SELECT
tb_TransactionDetails.TxnID,
tb_TransactionDetails.BranchCode,
tb_TransactionDetails.TxnDate,
tb_TransactionDetails.ReferenceNo,
tb_TransactionType.TxnTypeName,
tb_CurrencyCode.CCYDesc,
tb_TransactionDetails.CCYAmount,
tb_RecordStatus.StatusDesc,
(tb_TransactionName.FirstName + ' ' + ISNULL(tb_TransactionName.MiddleName,'') + ' ' + ISNULL(tb_TransactionName.LastName,'')) as 'Client',
(tb_TransactionName.AddressLine1 + ' ' + ISNULL(tb_TransactionName.AddressLine2, '') + ' ' + ISNULL(tb_TransactionName.AddressLine3, '')) as 'Address',
tb_TransactionName.WhoAdded,
tb_TransactionName.DateAdded,
ROW_NUMBER() OVER
(ORDER BY BranchCode ) AS RowNumber
FROM (((tb_TransactionType inner join tb_TransactionDetails
on tb_TransactionType.TxnTypeCode = tb_TransactionDetails.TxnType)
INNER JOIN tb_CurrencyCode on tb_TransactionDetails.CCYCode = tb_CurrencyCode.CCYCode)
inner join tb_RecordStatus on tb_TransactionDetails.RecordStatus = tb_RecordStatus.StatusCode)
LEFT JOIN tb_TransactionName
on tb_TransactionDetails.TxnID = tb_TransactionName.TxnID
WHERE BranchCode = '1003'
and TxnDate = '12/13/2013'
and one is getting all the users in the system:
select
USR.UserName,
USR.BranchID,
(ISNULL(USR.FirstName,'') + ' ' + ISNULL((SUBSTRING(USR.MiddleName,1,1) + '.' ),'') + ' ' + ISNULL(USR.LastName,'')) as 'Name',
MBS.IsLockedOut,
USR.LastActivityDate,
MAX(STUFF(fxMerge.RoleId, 1, 2, '')) as 'Roles'
from (aspnet_Membership as MBS inner join aspnet_Users as USR
on USR.ApplicationId = USR.ApplicationId and MBS.UserId = USR.UserId)
inner join aspnet_UsersInRoles UIR
on USR.UserId = UIR.UserId
CROSS APPLY(
SELECT ', ' + RoleName
FROM aspnet_UsersInRoles UIR1
INNER JOIN aspnet_Roles RM ON UIR1.RoleId = RM.RoleID
WHERE UIR.UserId = UIR1.UserId
FOR XML PATH('')) fxMerge (RoleId)
where USR.UserName = 'JSmith'
group by USR.UserName, USR.BranchID, USR.FirstName, USR.MiddleName, USR.LastName, MBS.IsLockedOut, USR.LastActivityDate
one thing I'm confused about, is that the 1st query does not need a GROUP BY clause, while the 2nd one does. My question is, why? I've been running the 1st query hundreds of times no problem in my system, without ever having the need of a GROUP BY clause, and the Gridview displays the expected results. While on my 2nd query, It's only when I add the long GROUP BY clause that the query executes successfully on the SQL Server Management studio, then nothing shows up on my Gridview.
That's because your second query has a MAX(). If you want the highest or lowest value, or the count or any other aggregate function, you'll need to specify how to group it.
Is Group by clause supported by this lib?
I wrote query Select SectionName, DepartmentName, SUM(SalesValue) FROM ( SELECT SectionName, Date, DepartmentName, SalesValue FROM StockDaily join Section on StockDaily.idSection=Section._id join Department on StockDaily.idDepartment = Department._id where idStore=1 and Date >=" + '"' + from + '"' + "and Date <=" + '"' + to + '"' + ")"+" Group by SectionName
It works in sqlite manager but in cod with lib not:/ Do you have any ideas?
Yes, sqlite supports GROUP BY aggregation. Here is the reference.
I have this SQL Statement:
de.SqlStatement = "SELECT A.Name, A.Catagory , COUNT(Patient_ID) AS PNO FROM PatientApplyToAssociation P INNER JOIN Association A on A.Association_ID = P.Association_ID WHERE A.Catagory='" & "health" & " '" & "' GROUP BY A.Name '"
with this Exception:
System.Data.SqlClient.SqlException was unhandled by user code
Class=16
ErrorCode=-2146232060
LineNumber=1
Message=Column
'Association.Name' is invalid in the select list because it is not
contained in either an aggregate function or the GROUP BY clause.
I had this exception when I added the where clause, It seems that the compiler cant see the Group By Section , because of the quotation ending before it, I tried to write it like this:
de.SqlStatement = "SELECT A.Name, A.Catagory , COUNT(Patient_ID) AS PNO FROM PatientApplyToAssociation P INNER JOIN Association A on A.Association_ID = P.Association_ID WHERE A.Catagory='" & "health" & "' GROUP BY A.Name '" & " '"
But it was an Incorrect syntax near ' '.
Any ideas?
I'm pretty sure you don't want the ' around the GROUP BY clause:
SELECT A.Name, A.Catagory
, COUNT(Patient_ID) AS PNO
FROM PatientApplyToAssociation P
INNER JOIN Association A
ON A.Association_ID = P.Association_ID
WHERE A.Catagory='" & "health" & " '" & " GROUP BY A.Name
In order to use the statement in your original question, you will need to revise it to be:
de.SqlStatement = "SELECT A.Name, A.Catagory, COUNT(1) AS PNO FROM PatientApplyToAssociation P INNER JOIN Association A on A.Association_ID = P.Association_ID WHERE A.Catagory='health' GROUP BY A.Name, A.Catagory"
There are 3 changes in this statement:
1) The extraneous string joins in the where and group by have been removed.
2) Group by A.Catagory has been added so that you will not receive another error similar to error in the question for this field.
3) COUNT(Patient_ID) has been changed to COUNT(1) as a possibly better practice. If the field you are counting contains nulls, it will not be included in the count. If this is the desired behavior, then your previous code was correct; otherwise you should use the revision.