How to prepend(?) number in text field with '0'? - sql

I have a text field in Microsoft Access which consists of only digits. I don't know if these digits are preceded by blank characters or not.
What I want to do is if the field has '1' I want to convert it to '0001', if it has '89' then I want to convert it to '0089', etc. Meaning I just want to make the field consistent in length of 4 characters and pad the number with the appropriate number of '0's.
How do I do this? Can I use the calculated field approach?
I can convert the database to SQL if SQL has an easy way to do this.
Thanks.

You can use the Format() function to transform the string of digits. Format() doesn't care whether or not the digits are preceded by spaces.
? Format("89","0000")
0089
? Format(" 89","0000")
0089
If you want to display those field values with that format in a query:
SELECT Format([YourTextField],"0000")
FROM YourTable;
If you want to change how they're stored:
UPDATE YourTable
SET [YourTextField] = Format([YourTextField],"0000");
Edit: #onedaywhen suggested a using CHECK CONSTAINT or Validation Rule to ensure your table only accepts valid data in the future. Here is a CHECK CONSTRAINT example:
ALTER TABLE YourTable
ADD CONSTRAINT four_digits_required
CHECK (
YourTextField LIKE '[0-9][0-9][0-9][0-9]'
);
You can run that statement from CurrentProject.Connection.Execute, which is an ADO object method. DDL statements with CHECK constraints can only be executed from ADO. So you could not execute that statement from CurrentDb.Execute, which is a DAO object method.
Alternatively this should work for YourTextField's Validation Rule property:
LIKE "[0-9][0-9][0-9][0-9]"
The Validation Rule approach would also allow you to use the Validation Text property to display a message to the user when submitted values are unacceptable:
"4 digits required."
In this situation the Validation Text approach is about the same as displaying the CHECK constraint name when that constraint is violated. However, if you wanted a more detailed message, the Validation Text could be a better choice.

You can try something like this:
RIGHT('0000' + TRIM(column), 4)

There are a few variations, here is another:
Left("0000", 4 - Len(Cstr(Trim(column)))) & Cstr(Trim(column))
Sometimes the Len command returns the length minus 1 with numeric values so the Cstr is there to avoid this.

Related

How to add constraint on the SQL when the data type is nvarchar?

I am learning how to add the check constraint, but it did not really work as I expected.
So, I have a column limit, which actually require some constraints, as some of the user broke our system when they enter record back end.
Column 'limit':
Constraint expected : If not NULL or Empty, then record must be float/numeric.
Can anyone help to solve this?
Thanks in advance!
You can use triggers to check numeric using ISNUMERIC(), and throw error if not. But this is bad design because you are not using database constraint but trigger validation.
I still suggest you add a new checklist column where user select by themself if CK_limit is empty or not.
I think this is what you are looking for SQL_VARIANT_PROPERTY.
Or you can use client side validations or you can use stored procedures to track this.
Do not use isnumeric() for the constraint. For instance, isnumeric() accepts the following as valid numbers:
'$'
'.'
'-'
'3e4'
Instead, use try_convert(). You can do:
(try_convert(float, limit) is not null or
limit is null or
limit = ''
)
However, the right solution is to simply use the correct data type for the column. Don't store numeric values in strings.

Can we select the datas that have spaces between the lines in DB without the spaces?

I have a textbox to make a search in my table.My table name is ADDRESSBOOK and this table holds the personel records like name,surname,phone numbers and etc.The phone numbers holding like "0 123 456789".If I write "0 123 456789" in my textbox in the background this code is working
SELECT * FROM ADDRESSBOOK WHERE phonenumber LIKE "0 123 456789"
My problem is how can I select the same row with writing "0123456789" in the textbox.Sorry for my english
You can use replace():
WHERE REPLACE(phonenumber, ' ', '') LIKE REPLACE('0 123 456789', ' ', '')
If performance is an issue, you can do the following in SQL Server:
alter table t add column phonenumber_nospace as (replace(phonenumber, ' ', '');
create index idx_t_phonenumber_nospace on t(phonenumber_nospace);
Then, remove the spaces in the parameter value before constructing the query, and use:
WHERE phonenumber_nospace = #phonenumber_nospace
This assumes an equality comparison, as in your example.
If there is a specific format in which the Phone number is stored than you can insert space at the specific locations and than pass that to the database query.
For Example as you have mentioned in the question for number 0 123 456789.
If there is a space after first number and space after fourth number then you could take the text from the textbox and insert space at second position and sixth position(as after adding space at second position + next three positions are number so sixth position) and pass that text to the database query.
An important part of Db design is ensuring data consistency. The more consistently it's stored, the easier it is to query. That's why you should make a point of ensuring your columns use the correct data types:
Dates/time columns should use an appropriate date/time type.
Number columns should use a numeric type of the appropriate size. (None of this numeric varchar rubbish.)
String columns should be of the appropriate length (whether char or varchar).
Columns with referential relationships should never store invalid references to the referenced table.
And similarly, you need to determine the exact format you wish to use when storing telephone numbers; and ensure that any time you store a number it's done so consistently.
Some queries will be complex enough as is. As soon as you're unable to rely on a consistent format, your queries to find data need to cater for all the possible variations. They'll be less likely to leverage indexes effectively.
I have seen argument in favour of storing telephone numbers as numeric data. (It is after all a "number".) Though I'm not really convinced because this approach would be unable to represent leading zeroes (which might be desirable).
Conclusion
Whenever you insert/update a telephone number, ensure it's stored in a consistent format. (NOTE: You can be flexible about how the number appears to your users. It's only the stored value that needs to be consistent.)
Whenever you search for a telephone number, convert the search value into the compatible format before searching.
It's up to you exactly where/how you do these conversions. But you might wish to consider CHECK constraints to ensure that if you failed to convert a number appropriately at some point, that it isn't accidentally stored in the incorrect format. E.g.
CONSTRAINT CK_NoSpacesInTelno CHECK (Telephone NOT LIKE '% %')

Like operator for integer

I have a column of type bigint (ProductSerial) in my table. I need to filter the table by the Product serial using like operator. But I found that, like operator can't be used for integer type.
Is there any other method for this (I don't want to use the = operator).
If you must use LIKE, you can cast your number to char/varchar, and perform the LIKE on the result. This is quite inefficient, but since LIKE has a high potential of killing indexes anyway, it may work in your scenario:
... AND CAST(phone AS VARCHAR(9)) LIKE '%0203'
If you are looking to use LIKE to match the beginning or the end of the number, you could use integer division and modulus operators to extract the digits. For example, if you want all nine-digit numbers starting in 407, search for
phone / 1000000 = 407
Although I'm a bit late to the party, I'd like to add the method I'm using to match the first N given numbers (in the example, 123) in any numeric-type column:
SELECT * FROM MyTable WHERE MyColumn / POWER(10, LEN(MyColumn) - LEN(123)) = 123
The technique is similar to #dasblinkenlight's one, but it works regardless of the number of digits of the target column values. This is a viable workaround if your column contain numbers with different length and you don't want to use the CAST+LIKE method (or a calculated column).
For additional details on that (and other LIKE workarounds) check out this blog post that I wrote on this topic.
If you have control over the database you could add a calculated column to copy the integer value to a string:
ALTER TABLE MyTable
ADD CalcCol AS (CAST(ProductSerial AS VARCHAR)) PERSISTED
And query like:
SELECT *
FROM MyTable
WHERE ProductSerial LIKE '%2548%'
This will move the calculation to the insert/update and only on rows inserted/updated rather then converting every row for each query.
This may be a problem if there are a lot of updated to columns as it will add a very small overhead to these.
There may be a way to do it mathematically using modulus but this would take a lot of working out and testing.
You can change your Field PhoneNumbers and store as String and then use the Like You can alter your table so that you can use the LIKE statement, if you still want to use BIGint for your phone numbers, you cannot get the exact Phone Number without using = the method you can use is Between method that looks for the Numbers that are inside the range.
For the edited question: I think you should use = sign for their ID, or convert the Int to String and then Use Like.
The original question related to a phone number. OP has since edited it to refer to serial numbers. This answer refers to the original question only.
My suggestion is to avoid storing your phone numbers as integers in the first place, and thus the problem does not occur. My phone number is in the form, internationally, of:
+44 7844 51515
Storing it as an integer makes no sense here, as you will never need to do any mathematical operation on it, and you would lose the leading plus. Within the UK, it is:
07844 51515
and thus storing it as an integer would lose its leading zero. Unless you have a very very specific requirement to store it as an integer, you would fare significantly better storing it as a string instead.
[Note: Not actually my phone number]

Add fraction constraint to a column in oracle

I am using oracle 10gr2. I am trying to enforce a constraint on a column called "score" such that only fractions can be entered.
More specifically, a the format should contain one digit in the numerator and one digit in the denominator, such that a user can only enter a fraction such as 3/4,2/5,or 7/8. The column only accepts numbers as the input. Can anyone show me the SQL to use?
If I understand correctly, I think the proper way to do this is to store the data in two columns. This especially makes sense if the top number is a user's actual score on a problem and the bottom number is the possible score, which is what it sounds like you are doing. This will enable you to sum up scores using the built in number functions in Oracle rather than parsing strings. Then, you limit the size of each column to (0-9) by using the type NUMBER(1,0). For example:
alter table table_name add (
column possible number(1,0),
column actual number(1,0)
);
If you have data in the score column already, you then copy your values over from there to your new columns. Finally, you drop that column.
alter table table_name drop score;
Also, I'd do a search on "Oracle less than constraint", because you probably don't want the actual score to exceed the possible, and probably do a similar constraint to make the possible score greater than zero.
I don't have an instance of Oracle to test against, but here are some pointers and some untested code:
Pointers:
Look here on how to create a check constraint: http://www.techonthenet.com/oracle/check.php
After you know that, you can use Regex to validate the input. Read here for further reference: http://psoug.org/reference/regexp.html
You are probably going to use REGEX_LIKE and it would look like something like this:
ALTER TABLE your_table
add CONSTRAINT check_your_field
CHECK (REGEXP_LIKE(your_field, '^[0-9]+/[0-9]+$'));
Warning: this is not guaranteed to be fully functional code. It's a lead. Read, research and adjust accordingly.
A caveat: 1/0 will be considered valid by the Regex above, but we all know it should not be. There's a way you can know about the second part of the fraction. Read the Regex link, everything you need to know is there.
The domain of valid values is finite and small. Therefore, consider putting them all in a table, using a fixed width text column (i.e. three characters) and a create a foreign reference to this lookup table, rather than a CHECK constraint.

MS-Access - why can't this update query fill empty cells?

In MS-Access database, table called NewTable3
colname is a text column containing lot of empty cells or blanks.
i want to put ? character in empty cells . when i run the query
UPDATE NewTable3 SET colname = '?' WHERE ISNULL(colname) ;
This query updates 0 records why . what is wrong with this query
Two quick things:
1) Try putting the colname in square brackets.
2) Remember that empty cells (Nulls) and empty strings ("") are different.
Together:
UPDATE NewTable3 SET [colname] = "?" WHERE ISNULL([colname]) OR [colname] = "";
Also, are you running the query in Access itself, or just using the Access engine and using the data in another program/via a VBA script? It can make a difference.
EDIT:
Based on #onedaywhen's prodding, I now see that I never fully absorbed the original question, which was asking about replacing Nulls with the literal ? character. This is insane and not helpful or useful. If you don't have a meaningful default value for the field, then LEAVE IT NULL. If you want to distinguish between Null (unknown) and Blank (i.e., known to be blank), you can allow zero-length strings and change the Nulls to ZLS.
My original post follows, since I think it is useful for people who might get to this crazy question needing to do things properly:
In total, all the answers in this thread end up solving all the problems with the original SQL statement, but they do so incompletely, so I'll compile them all together in an attempt to create a comprehensive correct answer.
#Wim Hollebrandse wisely points out that a parameter needs brackets, but posts the SQL as:
UPDATE NewTable3 SET colname = '[?]' WHERE ISNULL(colname);
This is incorrect, in that the quotes will cause what's inside them to be treated literally, instead of evaluated as a paramter, so you'll end up with all your fields updated to the literal value "[?]". The correct syntax would be:
UPDATE NewTable3 SET colname = [?] WHERE ISNULL(colname);
#GuinnessFan points out a problem in the WHERE clause, suggesting out that the result of IsNull() needs to be compared to True in order for the WHERE clause to work. In other words, this:
WHERE IsNull(NewTable3.colname)
...should be this:
WHERE IsNull(NewTable3.colname)=True
But given that both statements evaluate the same, they are entirely equivalent. But #GuinnessFan is correct that this is the best syntax:
WHERE NewTable3.colname Is Null
#mavnn points out that the fields may be "empty" while not being Null, which is a very common problem. I believe on principle (and consistent with my understanding of the official SQL standards) that fields should be initialized as Null and should not allow zero-length strings. It is certainly possible in some applications that one might want to distinguish Null, i.e., value not yet supplied, from blank (zero-length string), i.e., value known to be blank. But if that's part of the application design, then the user should know that criteria on such fields need to consider whether one or both should be included (i.e., both Null and <>"" or one or the other).
From my point of view, it was unfortunate that the the old default for text fields (where AllowZLS defaulted to FALSE) was changed in Access 2003 to allow ZLS's by default. This means that many people who don't notice that AllowZLS is set to TRUE when they create their tables end up with ZLS's stored in their text fields without intending to do so (and importing a table from a previous version also defaults to TRUE).
While testing for Null and ="" will make the WHERE clause that is seeking all "empty" fields work as expected, the permanent fix is to change the field definition to disallow ZLS's. But do note that changing AllowZLS to FALSE does not clear the existing ZLS's -- you have to run a SQL UPDATE to remove them.
Last of all, in using parameters, it is better to declare them such that the values that the user can input are restricted to appropriate values. If the field is numeric, you to limit it to numeric values, if a date, date values, if text or memo, to text:
PARAMETERS [User Prompt] Long;
UPDATE MyTable SET LongIntegerColumn = [User Prompt]
PARAMETERS [User Prompt] DateTime;
UPDATE MyTable SET DateColumn = [User Prompt]
PARAMETERS [User Prompt] Text ( 255 );
UPDATE MyTable SET TextColumn = [User Prompt]
Note that with Text(255) as your parameter type, anything supplied by the user is truncated to 255 characters, even if it's longer than that (it would be a pretty unusual situation where'd you'd need that). For values longer than that (such as memo fields), you omit the text length declaration:
PARAMETERS [User Prompt] Text;
UPDATE MyTable SET TextColumn = [User Prompt]
In any event, I think so-called anonymous parameters are not too helpful, as you aren't leveraging the power of parameters to restrict data type of input criteria.
Try:
UPDATE NewTable3 SET colname = '[?]' WHERE ISNULL(colname);
The questionmark is used for anonymous parameters, so you need to escape it as above. Note that I have not tried this.
UPDATE NewTable3 SET NewTable3.colname = "?"
WHERE (((NewTable3.colname) Is Null));
To keep your function: WHERE (((IsNull([NewTable3.colname]))=True));
I don't believe that replacing the NULL value with your own 'magic' value ? will cause you anything but further pain.
Here's hoping you may draw inspiration from this article:
How To Handle Missing Information Without Using (some magic value)