'69 Camaro wrote:
Hi Gunny,
You would rather the developer store eight characters...
instead of storing a four byte Long
Yes. It's a basic data modelling approach: if the data in the reality
is fixed width text then model it as fixed width text. I'm not against
exploiting the software to perform integer operations on text data
which contain only numeric characters, in which case store it as fixed
width text as cast it as integer at the developer's convenience.
Dang! You don't much like Access users and developers, do you? ;-)
You would rather the developer store eight characters (or 16 if
Unicode compression is avoided), and create a validation rule to ensure that
only digits are stored in the column, instead of storing a four byte Long
that needs no such Validation Rule or leading zeros?
If storage has become such an issue that you will consider modelling
fixed width text as integer to save disk space, it is probably time to
port to a platform more capable than Access/Jet.
All this so that the
developer doesn't have to write a simple formatting function that displays
the digits with leading zeros?
That's not my point. I always say that the developer(s) should write
both 'server side' procedures and 'client side' as appropriate e.g.
more appropriate to do text formatting on the 'client side'. As a
part-time developer myself, I'm not afraid of putting in the extra
effort
You would rather the users type in all eight digits, including the leading
zeros?
No. I would think it would be better to handle such formatting (e.g.
padding with zeros) on the 'client side', especially in Access/Jet
where you only get to perform one SQL command per procedure. However, I
do agree that the 'server side' procs should handle data without the
leading zeros. For example:
CREATE TABLE Accounts (
account_nbr CHAR(8) NOT NULL PRIMARY KEY,
CONSTRAINT account_nbr__pattern
CHECK (account_nbr LIKE '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]')
)
;
CREATE PROCEDURE AccountAdd (
arg_account_nbr CHAR(8)
)
AS
INSERT INTO Accounts (account_nbr)
VALUES (RIGHT$('00000000' & arg_account_nbr, 8))
;
EXECUTE AccountAdd '5'
;
EXECUTE ACCOUNTADD 55
;
EXECUTE AccountAdd 'Will fail'
;
That last one generates an error which can be trapped on the 'client
side'. Here's an alternative approach where the error is avoided and
only the number of rows affected need be tested:
DROP PROCEDURE AccountAdd
;
CREATE PROCEDURE AccountAdd (
arg_account_nbr CHAR(8)
)
AS
INSERT INTO Accounts (account_nbr)
SELECT DISTINCT RIGHT$('00000000' & arg_account_nbr, 8) AS account_nbr
FROM Accounts
WHERE RIGHT$('00000000' & arg_account_nbr, 8)
LIKE '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
;
I must have the buggy version of Access
OK, here's a demo of my SQL code which doesn't use Access:
Sub testGunny()
Dim cat As Object
Set cat = CreateObject("ADOX.Catalog")
With cat
.Create _
"Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=C:\DropMe.mdb;"
With .ActiveConnection
.Execute _
"CREATE TABLE Accounts ( account_nbr CHAR(8)" & _
" NOT NULL PRIMARY KEY, CONSTRAINT" & _
" account_nbr__pattern CHECK (account_nbr LIKE" & _
" '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]')" & _
" );"
.Execute _
"CREATE PROCEDURE AccountAdd ( arg_account_nbr" & _
" CHAR(8) ) AS INSERT INTO Accounts (account_nbr)" & _
" VALUES (RIGHT$('00000000' & arg_account_nbr," & _
" 8)); "
.Execute _
"EXECUTE AccountAdd '5';"
.Execute _
"EXECUTE AccountAdd 55;"
Dim lRows As Long
On Error Resume Next
.Execute _
"EXECUTE AccountAdd 'Will fail';", lRows
MsgBox _
"Error: " & _
IIf(Len(Err.Description) = 0, "(none)", _
Err.Description) & vbCr & vbCr & _
"Rows affected: " & CStr(lRows)
On Error GoTo 0
.Execute _
"DROP PROCEDURE AccountAdd;"
.Execute _
"CREATE PROCEDURE AccountAdd ( arg_account_nbr" & _
" CHAR(8) ) AS INSERT INTO Accounts (account_nbr)" & _
" SELECT DISTINCT RIGHT$('00000000' & arg_account_nbr," & _
" 8) AS account_nbr FROM Accounts WHERE RIGHT$('00000000'" & _
" & arg_account_nbr, 8) LIKE
'[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]';"
lRows = 0
On Error Resume Next
.Execute _
"EXECUTE AccountAdd 'Will fail';", lRows
MsgBox _
"Error: " & _
IIf(Len(Err.Description) = 0, "(none)", _
Err.Description) & vbCr & vbCr & _
"Rows affected: " & CStr(lRows)
On Error GoTo 0
End With
End With
End Sub
Jamie.
--