Link to home
Start Free TrialLog in
Avatar of Coast Line
Coast LineFlag for Canada

asked on

How i use this Same Update Multiple in Coldfusion MX 7

My Question is we have worked with the solution and make it worked but the Coldfusion version 8 is used using the <cfdbinfo> tag. I have the following CFC. how can i use and test following the CFC to make it work with Coldfusion 7:
Here is the CFC:
 
<cfcomponent>
    <cffunction name="init" returntype="AccessDBUtil" access="public" >
        <cfargument name="jdbcDatasourceName" type="string" required="true" />
        <cfset setDatasourceName(arguments.jdbcDatasourceName)  />
        <cfreturn this  />
    </cffunction>
    
    <cffunction name="setDatasourceName" returntype="void" access="private" >
        <cfargument name="jdbcDatasourceName" type="string" required="true" />
        <cfset variables.instance.datasource = arguments.jdbcDatasourceName  />
    </cffunction>
    <cffunction name="getDatasourceName" returntype="string" access="public" >
        <cfreturn variables.instance.datasource  />
    </cffunction>
    
    <cffunction name="getCatologs" returntype="query" access="public" >
        <cfset var Local = structNew() />
 
        <cfset Local.connection = getConnection() />
        <cfset Local.resultset = Local.connection.getMetaData().getCatalogs()  />
        <cfset Local.query = resultsetToQuery( resultset = Local.resultset )  />
        <cfset Local.resultset.close()  />
        <cfset Local.connection.close() />
 
        <cfreturn Local.query   />
    </cffunction>
    
    <cffunction name="getSchemas" returntype="query" access="public" output="true" >
        <cfset var Local = structNew() />
 
        <cfset Local.connection = getConnection() />
        <cfset Local.resultset = Local.connection.getMetaData().getSchemas()  />
        <cfset Local.query = resultsetToQuery( resultset = Local.resultset )  />
        <cfset Local.resultset.close()  />
        <cfset Local.connection.close() />
 
        <cfreturn Local.query   />
    </cffunction>
 
    <cffunction name="getTableTypes" returntype="query" access="public" >
        <cfset var Local = structNew() />
        
        <cfset Local.connection = getConnection() />
        <cfset Local.resultset = Local.connection.getMetaData().getTableTypes()  />
        <cfset Local.query = resultsetToQuery( resultset = Local.resultset )  />
        <cfset Local.resultset.close()  />
        <cfset Local.connection.close() />
        
        <cfreturn Local.query   />
    </cffunction>
 
    <cffunction name="getProcedures" returntype="query" access="public" output="false" >
        <cfargument name="catalogName" type="string" required="false" hint="The name of a catolog in the database. An empty string means retrieve objects without a catalog. If not specified, the catolog is not used to narrow the search"  />
        <cfargument name="schemaPattern" type="string" required="false" default="%" hint="The name of a schema in the database. An empty string means retrieve objects without a schema. "  />
        <cfargument name="procedurePattern" type="string" required="false" default="%" />
        <cfset var Local = structNew() />
                
        <cfscript>
            Local.isCatalogNonNull =  structKeyExists(arguments, "catalogName");
            Local.isSchemaNonNull =  structKeyExists(arguments, "schemaPattern");
            Local.connection = getConnection();
 
            //TODO: check if there is a way to pass java NULL's conditionally 
            if ( Local.isCatalogNonNull AND Local.isSchemaNonNull ) {
                Local.resultset = Local.connection.getMetaData().getProcedures( arguments.catalogName, 
                            arguments.schemaPattern, 
                            arguments.procedurePattern );
            }
            else if ( Local.isCatalogNonNull ) {
                Local.resultset = Local.connection.getMetaData().getProcedures( arguments.catalogName, 
                            javacast("null", ""), 
                            arguments.procedurePattern );
            }        
            else if ( Local.isSchemaNonNull ) {
                Local.resultset = Local.connection.getMetaData().getProcedures( javacast("null", ""), 
                            arguments.schemaPattern, 
                            arguments.procedurePattern );
            }        
            else {
                Local.resultset = Local.connection.getMetaData().getProcedures( javacast("null", ""), 
                            javacast("null", ""),
                            arguments.procedurePattern );
            }        
 
            Local.query = resultsetToQuery( resultset = Local.resultset );
            Local.resultset.close();
            Local.connection.close();
        </cfscript>
 
        <cfreturn Local.query   />
    </cffunction>
 
    
    <cffunction name="getTables" returntype="query" access="public" output="false" >
        <cfargument name="catalogName" type="string" required="false" hint="The name of a catolog in the database. An empty string means retrieve objects without a catalog. If not specified, the catolog is not used to narrow the search"  />
        <cfargument name="schemaPattern" type="string" required="false" default="%" hint="The name of a schema in the database. An empty string means retrieve objects without a schema. "  />
        <cfargument name="tablePattern" type="string" required="false" default="%" />
        <cfargument name="typeList" type="string" required="false" default="" hint="Comma delimited list of table types to include. An empty string means retrieve all types" />
        <cfset var Local = structNew() />
                
        <cfscript>
            Local.isCatalogNonNull =  structKeyExists(arguments, "catalogName");
            Local.isTypeNonNull =  len(trim(arguments.typeList));
            Local.typeArray        = listToArray(arguments.typeList);
            Local.connection = getConnection();
 
            //TODO: check if there is a way to pass java NULL's conditionally 
            if ( Local.isCatalogNonNull AND Local.isTypeNonNull ) {
                Local.resultset = Local.connection.getMetaData().getTables( arguments.catalogName, 
                            arguments.schemaPattern, 
                            arguments.tablePattern, 
                            Local.typeArray);
            }
            else if ( Local.isCatalogNonNull ) {
                Local.resultset = Local.connection.getMetaData().getTables( arguments.catalogName, 
                            arguments.schemaPattern, 
                            arguments.tablePattern, 
                            javacast("null", ""));
            }        
            else if ( Local.isTypeNonNull ) {
                Local.resultset = Local.connection.getMetaData().getTables( javacast("null", ""), 
                            arguments.schemaPattern, 
                            arguments.tablePattern, 
                            Local.typeArray); 
            }        
            else {
                Local.resultset = Local.connection.getMetaData().getTables( javacast("null", ""), 
                            arguments.schemaPattern, 
                            arguments.tablePattern, 
                            javacast("null", "")); 
            }
 
            Local.query = resultsetToQuery( resultset = Local.resultset );
            Local.resultset.close();
            Local.connection.close();
        </cfscript>
 
        <cfreturn Local.query   />
    </cffunction>
 
    <cffunction name="getColumns" returntype="query" access="public" output="false" >
        <cfargument name="catalogName" type="string" required="false" hint="The name of a catolog in the database. An empty string means retrieve objects without a catalog. If not specified, the catolog is not used to narrow the search"  />
        <cfargument name="schemaPattern" type="string" required="false" hint="The name of a schema in the database. An empty string means retrieve objects without a schema. If not specified, the schema is not used to narrow the search"  />
        <cfargument name="tablePattern" type="string" required="false" default="%" hint="Table name to find. Wildcards are NOT supported by com.inzoom.jdbcado driver"  />
        <cfargument name="columnPattern" type="string" required="false" default="%" hint="Column name to find. Wildcards are NOT supported by com.inzoom.jdbcado driver"  />
        <cfset var Local = structNew() />
                
        <cfscript>
            Local.isCatalogNonNull =  structKeyExists(arguments, "catalogName");
            Local.isSchemaNonNull =  structKeyExists(arguments, "schemaPattern");
            Local.connection = getConnection();
 
            //TODO: check if there is a way to pass NULL's conditionally 
            if ( Local.isCatalogNonNull AND Local.isSchemaNonNull ) {
                Local.resultset = Local.connection.getMetaData().getColumns( arguments.catalogName, 
                            arguments.schemaPattern, 
                            arguments.tablePattern, 
                            arguments.columnPattern);
            }
            else if ( Local.isCatalogNonNull ) {
                Local.resultset = Local.connection.getMetaData().getColumns( arguments.catalogName, 
                            javacast("null", ""), 
                            arguments.tablePattern, 
                            arguments.columnPattern);
            }        
            else if ( Local.isSchemaNonNull ) {
                Local.resultset = Local.connection.getMetaData().getColumns( javacast("null", ""), 
                            arguments.schemaPattern, 
                            arguments.tablePattern, 
                            arguments.columnPattern);
            }
            else {
                Local.resultset = Local.connection.getMetaData().getColumns( javacast("null", ""), 
                            javacast("null", ""), 
                            arguments.tablePattern, 
                            arguments.columnPattern);
            }
 
            Local.query = resultsetToQuery( resultset = Local.resultset );
            //Local.query2 = createObject("java", "coldfusion.sql.QueryTable").init(Local.resultset);
            Local.resultset.close();
            Local.connection.close();
        </cfscript>
 
        <cfreturn Local.query   />
    </cffunction>
    
    <cffunction name="getVersionInfo" returntype="query" access="public" >
        <cfset var Local = structNew() />
                
        <cfscript>
            Local.query = queryNew( "DATABASE_VERSION,DATABASE_PRODUCTNAME" & 
                                ",DATABASE_MAJOR_VERSION,DATABASE_MINOR_VERSION," & 
                                ", DRIVER_VERSION,DRIVER_NAME,JDBC_MAJOR_VERSION," &
                                "JDBC_MINOR_VERSION");
                            
            Local.connection = getConnection();
            Local.meta = getConnection().getMetaData();
        
            Local.row = queryAddRow( Local.query, 1);
            Local.query["DATABASE_PRODUCTNAME"][Local.row]         = Local.meta.getDatabaseProductName();
            Local.query["DATABASE_VERSION"][Local.row]             = Local.meta.getDatabaseProductVersion();
            Local.query["DATABASE_MAJOR_VERSION"][Local.row]     = Local.meta.getDatabaseMajorVersion();
            Local.query["DATABASE_MINOR_VERSION"][Local.row]     = Local.meta.getDatabaseMinorVersion();
            Local.query["DRIVER_VERSION"][Local.row]             = Local.meta.getDriverVersion();
            Local.query["DRIVER_NAME"][Local.row]                 = Local.meta.getDriverName();
            Local.query["JDBC_MAJOR_VERSION"][Local.row]         = Local.meta.getDriverMajorVersion();
            Local.query["JDBC_MINOR_VERSION"][Local.row]         = Local.meta.getDriverMinorVersion();
    
            Local.connection.close();
        </cfscript>
        
        <cfreturn Local.query  />
    </cffunction>
 
 
    <cffunction name="getConnection" returntype="any" >
        <cfset var dsService = createObject("java", "coldfusion.server.ServiceFactory").getDataSourceService()  />
        <cfset var connection = dsService.getDataSource(getDatasourceName()).getConnection()  />
        <cfreturn connection  />
    </cffunction>
    
    <cffunction name="getResultSetColumnNames" returntype="array" access="private" hint="Returns an array of column names from the resultset metadata" >
        <cfargument name="resultsetMetadata" type="any" required="true" />
        <cfset var Local = structNew()  />
        
        <cfscript>
            Local.columnArray = arrayNew(1);
            //get number of columns in the resulset
            Local.maxColumn = arguments.resultsetMetadata.getColumnCount();
            //get the name of each column in the query and append it to the array
            for (Local.index = 1; Local.index LTE Local.MaxColumn; Local.index = Local.index + 1) {
                arrayAppend( Local.columnArray, arguments.resultsetMetadata.getColumnName( javacast("int", Local.index)) );        
            }
        </cfscript>
        
        <cfreturn Local.columnArray  />
    </cffunction>
    
    <cffunction name="resultsetToQuery" returntype="query" access="private" hint="Converts a resulset to a query object" >
        <cfargument name="resultset" type="any" required="true" />
        <cfset var Local = structNew()  />
        
        <!--- could also use "coldfusion.sql.QueryTable" to create a resulset 
        <cfset Local.query = createObject("java", "coldfusion.sql.QueryTable").init(arguments.resultset) />
        --->
        
        <cfscript>
            Local.columnNames     = getResultSetColumnNames( arguments.resultset.getMetaData() );
            Local.maxColumn     = arrayLen( Local.columnNames );
            Local.query         = queryNew( arrayToList(Local.columnNames) );
            
            while ( arguments.resultset.next() ) {
                //add one row to the query for each row in the resultset
                Local.rowIndex = queryAddRow(Local.query , 1);
                 for ( Local.colIndex = 1; Local.colIndex LTE Local.maxColumn; Local.colIndex = Local.colIndex + 1) {
                    Local.colName = Local.columnNames[Local.colIndex];
                    Local.value = arguments.resultset.getObject( Local.colName );
                    // if the returned value is not NULL
                    if ( structKeyExists(Local, "value") ) {
                        Local.query[Local.colName][Local.rowIndex] = Local.value;
                    }
                }
            }
        </cfscript>
                
        <cfreturn Local.query  />
    </cffunction>
    
</cfcomponent>
 
Now this is how i Invoke it:
 
<cfset dbUtil = createObject("component", "AccessDBUtil").init("#session.newdsn#") />
<cfset qVersion = dbUtil.getVersionInfo() />
<cfset qCatalogs = dbUtil.getCatologs() />
<cfset qProcedures = dbUtil.getProcedures() />
<cfset qTableTypes = dbUtil.getTableTypes() />
<cfset qSchemas = dbUtil.getSchemas() />
<cfset qTables = dbUtil.getTables(typeList = "Table") />
<cfset qColumns = dbUtil.getColumns(tablePattern = "Table1") />
 
 
<cfdump var="#qProcedures#"/>
<cfdump var="#qColumns#"/>
<cfdump var="#qTables#"/>
<cfdump var="#qSchemas#"/>
<cfdump var="#qTableTypes#"/>
<cfdump var="#qVersion#"/>
<cfdump var="#qCatalogs#"/>
 
But I get the following Error:
 
 
 
 The web site you are accessing has experienced an unexpected error.
Please contact the website administrator.
 
The following information is meant for the website developer for debugging purposes.
Error Occurred While Processing Request
Element NEWDSN is undefined in SESSION.
 
The error occurred in C:\Inetpub\wwwroot\Classic\test.cfm: line 1
 
1 : <cfset dbUtil = createObject("component", "AccessDBUtil").init("#session.newdsn#") />
2 : <cfset qVersion = dbUtil.getVersionInfo() />
3 : <cfset qCatalogs = dbUtil.getCatologs() />

Open in new window

Avatar of Coast Line
Coast Line
Flag of Canada image

ASKER

Please check the Related  Solution to this question as related question is already solved but that worked with coldfusion 8 and now i am trying with coldfusion 7
The problem is a simple variable is undefined issue.

You are indicating that your datasource is stored in    session.newDSN
But apparently, that variable is not defined.  

What variable is holding your datasource?    If it is  session.newDSN, make sure it is populated, otherwise change the variable to the correct one.


Element NEWDSN is undefined in SESSION.
 
The error occurred in C:\Inetpub\wwwroot\Classic\test.cfm: line 1
 
1 : <cfset dbUtil = createObject("component", "AccessDBUtil").init("#session.newdsn#") />

I solved it. thanks man, But i think using <cfdbinfo> lists the Is_Primary Key of access database.

but i use the above cfc and lists all the stuuf. it does not the IS_PRIMARY KEY and it works only with Microsoft Access with Unicode, if i use with simple Access, it shows optional feature not implemented.

I am attaching the file structure it shows when i run the query.

I heared from here that we can use com objects to get the same as we do in cfdbinfo to find the table structure if it somehow does not work with access.

is there any way we can do it.

Please experts

untitled.GIF
My suggestion is to make a list of the primary keys for each table used.   This is a reliable approach, it's not practicle if you have tons of tables who's primary key name is not the table name.

How many tables do you have?

Do you know the primary key field for each table?
they are hello lots of tables,

i have one more approach but i am sure will it work or not: this is the foolowing cfc to get tblstructure:

when i run the CFC the CFC Contents:

<cffunction name="getDBTableStruct" access="public" returntype="array" output="no" hint="I return the structure of the given table in the database.">
  <cfargument name="tablename" type="string" required="yes">
  <cfscript>
    var qRawFetch = 0;
    var arrStructure = 0;
    var tmpStruct = StructNew();
    var i = 0;

    var PrimaryKeys = 0;
    var TableData = ArrayNew(1);
    </cfscript>
  <cfset qRawFetch = runSQL("SELECT TOP 1 * FROM #arguments.tablename#")>
  <cfset arrStructure = getMetaData(qRawFetch)>
  <cfif isArray(arrStructure)>
    <cfloop index="i" from="1" to="#ArrayLen(arrStructure)#" step="1">
      <cfset tmpStruct = StructNew()>
      <cfset tmpStruct["ColumnName"] = arrStructure[i].Name>
      <cfset tmpStruct["CF_DataType"] = getCFDataType(arrStructure[i].TypeName)>
      <!--- %% Ugly guess --->
      <cfif arrStructure[i].TypeName eq "COUNTER" OR ( i eq 1 AND arrStructure[i].TypeName eq "INT" AND Right(arrStructure[i].Name,2) eq "ID" )>
        <cfset tmpStruct["PrimaryKey"] = true>
        <cfset tmpStruct["Increment"] = true>
        <cfset tmpStruct["AllowNulls"] = false>
        <cfelse>
        <cfset tmpStruct["PrimaryKey"] = false>
        <cfset tmpStruct["Increment"] = false>
        <cfset tmpStruct["AllowNulls"] = true>
      </cfif>
      <!--- %% Ugly guess --->
      <cfif isStringType(arrStructure[i].TypeName) AND NOT tmpStruct["CF_DataType"] eq "CF_SQL_LONGVARCHAR">
        <cfset tmpStruct["length"] = 255>
      </cfif>
      <cfset tmpStruct["Special"] = "">
      <cfif Len(tmpStruct.CF_DataType)>
        <cfset ArrayAppend(TableData,StructCopy(tmpStruct))>
      </cfif>
    </cfloop>
    <cfelse>
    <cfthrow message="DataMgr can currently only support MS Access on ColdFusion MX 7 and above unless tables are loaded using loadXML(). Sorry for the trouble." type="DataMgr" detail="NoMSAccesSupport">
  </cfif>
  <cfreturn TableData>
</cffunction>
See attached image:

Now we have this line in above question our code[see related solution for fuull details]:

<cfdbinfo name="getDataInfo" datasource="#session.newdsn#" table="#FORM.tableName#" type="columns">
<cfloop query="getDataInfo">
            <cfif getDataInfo.IS_PRIMARYKEY>
                <cfset FORM.PKcolumn = getDataInfo.COLUMN_NAME>
                <cfbreak>
            </cfif>
        </cfloop>

I want to replace the above line to work with coldfusion 7. and replace with something that work with coldfusion 7

untitled.GIF
i think no expert want to help me out in this. The problem is a little difficult but i hope to get a better answer from any answer. I know many are there but i think my question is being neglected.

Can i ask Why?

this should find your primary key from that function..
<cfset myTable = getDBTableStruct("the_table_name")>
<cfloop index="arrayPos" from="1" to="#arrayLen(myTable)#">
   <cfif myTable[arrayPos].primaryKey is true>
       <cfset FORM.PKcolumn = myTable[arrayPos].columnName>
       <cfbreak>
   </cfif>
</cfloop>

Open in new window

referencing this line:

<cfset myTable = getDBTableStruct("the_table_name")>
will automatically get the CFC to load or i need to load the CFC using the cfinvoke tag.

Open in new window

The code show it as a simple function, so I called it as such.  If it's actually inside a cfc than you can invoke or createobject; whatever is your usual preference..
That worked perfect as i checked, but it does not show me the updated records, while i check the in database, records get updated but when i try clear session, cookies, and everything i try editting again. it again displays the old values which i had changed.

is that why because i am using session.newdsn...

but if i use request scope. that is dynamically loaded on the selection of datasource, it always show me newdsn is undefined in request.

i cannot application as it will keep that binding

what could be the valid way to do it.

Works perfect with data but does not show updated data while data is updated in database.

Access using
The datasource may be unrelated to your issue.   But to answer your question, application scope would be the best scope to use.   Application scope is set once and is used by all users.   Are you changing your datasource at all?   If so, how?   If your datasource is always the same, then application. is the way to go.

Can you post your latest code, I will see if I can tell why it's not keeping the update.
here is below the little code what i am doing. selecting datasource dynamicallly and then using them below to list all tables and edit rows etc.



<cfform method="post" action="index.cfm">
  <tr>
    <td>Choose Database:</td>
    <td><cfset conn = createObject("java","coldfusion.server.ServiceFactory")>
    <cfset dbList = listSort(structKeyList(conn.DataSourceService.getDatasources()),"textnocase")>
    <select name="databasename">
    <option value="0">Selecte One...</option>
	<cfoutput>
    	<cfloop list="#dbList#" index="dsnName">
        	<option value="#dsnName#">#dsnname#</option>
    	</cfloop>
	</cfoutput>
    </select>
    </td>
  </tr>
  <tr>
    <td width="19%"><cfinput type="radio" name="dsntype" value="MYSQL">
      <br /></td>
    <td width="81%">My SQL</td>
  </tr>
  <tr>
    <td><cfinput type="radio" name="dsntype" value="mssql"></td>
    <td>Microsoft SQL Server</td>
  </tr>
  <tr>
    <td><cfinput type="radio" name="dsntype" value="access"></td>
    <td>Ms-Access</td>
  </tr>
  <tr>
    <td>&nbsp;</td>
    <td><input name="choosemode" type="submit" class="submitform" id="choosemode" value="Select DSN" /></td>
  </tr>
  </cfform>
 
 
<cfif isdefined('form.choosemode')>
	<cfif form.dsntype IS 'MYSQL'>
    	<cfset request.dsntype = "mysql">
    	<cfset request.newdsn = "#form.databasename#">
    <cfelseif form.dsntype IS 'mssql'>
    	<cfset request.dsntype = "mssql">
    	<cfset request.newdsn = "#form.databasename#">
    <cfelse>
    	<cfset request.dsntype = "access">
    	<cfset request.newdsn = "#form.databasename#">
    </cfif>
    <cflocation addtoken="no" url="home.cfm">
</cfif>

Open in new window

i replaced the request with session:

<cfif isdefined('form.choosemode')>
	<cfif form.dsntype IS 'MYSQL'>
    	<cfset session.dsntype = "mysql">
    	<cfset session.newdsn = "#form.databasename#">
    <cfelseif form.dsntype IS 'mssql'>
    	<cfset session.dsntype = "mssql">
    	<cfset session.newdsn = "#form.databasename#">
    <cfelse>
    	<cfset session
.dsntype = "access">
    	<cfset session.newdsn = "#form.databasename#">
    </cfif>
    <cflocation addtoken="no" url="home.cfm">

</cfif>

Open in new window

So you are using several databases?

Does that code work?   You cannot set a session variable and then do a CFLOCATION after it, the session variable requires the request to end completely in order to be written into the cookie/registry.  Since you are doing a CFLOCATION it is interupting the request and may not allow the values to be set.

Session is an OK choice provided each user may have a different datasource and that datasource will remain for the majority of their time on the site.


Let's do one thing at a time.  Try hard-coding your datasource (put in the actual datasource name not the variable) and see if your code is working.  

Then put in a <cfoutput> statement when you do your SQL INSERT/UPDATE to see what datasource it is using  <cfoutput>#session.newdns#</cfoutput>

Fool me Dude!!!

i was having the cachedwithin attribute with a 10 minute timeframe, i removed it and it worked awesome:

well in in Coldfusion 7 i had this:

wriiten in coldfusion 8

<cfloop array="#getmetadata(getData)#" index="colStruct">
                <cfif colStruct['TypeName'] is 'COUNTER'>
                    <cfset FORM.PKcolumn = colStruct['Name']>
                    <cfbreak>
                </cfif>
            </cfloop>
how i can write in coldfusion 7
ASKER CERTIFIED SOLUTION
Avatar of gdemaria
gdemaria
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Yes! Thanks, Well Even Before you added the answer, i already tried that and it worked. But thanks for all your above help.

Regards