Forum Discussion

Montreux's avatar
Montreux
New Contributor III
2 years ago

ID Field in Custom SQL and Setting a Unique Default for New Rows

Hi, I have a custom SQL table for people planning and want an ID field as my primary key.  (The existing fields that would be good for a primary key need to editable (e.g. entry date) so I cannot u...
  • RobbSalzmann's avatar
    RobbSalzmann
    2 years ago

    Montreux Yes, I use Dashboard Extenders for this.  Here's some example code to help you get started.  I almost never use the STE's internal save/update functionality.  Besides being fussy and undocumented, it doesn't (that I know of) stub out for data validation.

     

    Private Function SaveRecords(si As SessionInfo, args As DashboardExtenderArgs) As Object
      Dim strSql As String = String.Empty
      Dim strDate As String = String.Empty
      Dim saveDataTaskResult As Object = Nothing
      Dim pKTheId As String = String.Empty
      Dim strValidationMsg = String.Empty
    
      Try
        'Not cancelling the default save even though nothing will be saved using the STE allows the UI to refresh with the new values
        saveDataTaskResult = New XFSqlTableEditorSaveDataTaskResult() With {
          .IsOK = True,
          .ShowMessageBox = False,
          .Message = "",
          .CancelDefaultSave = False
        }
        pKTheId = args.NameValuePairs.XFGetValue("pKTheId", "0")
        For Each row As XFEditedDataRow In args.SqlTableEditorSaveDataTaskInfo.EditedDataRows
          'Add any data validation here
          strValidationMsg = ValidateRecord(si, args, row)
          strDate = Date.Parse(row.ModifiedDataRow.Item("CustomDate")).ToString("yyyy-MM-dd")
          strSql = $"UPDATE XFW_CustomTable SET CustomAmount={row.ModifiedDataRow.Item("CustomAmount")}, Descr='{row.ModifiedDataRow.Item("Descr")}' WHERE CustomDate='{strDate}' and pKTheId={pKTheId}"
          Using DbConn As DbConnInfo = BRApi.Database.CreateApplicationDbConnInfo(si)
            BRApi.Database.ExecuteSql(DbConn, strSQL, True)
          End Using
        Next
        'We already added the new/updated records.  No need to use the SqlTableEditor to do it - so we clear them here.
            args.SqlTableEditorSaveDataTaskInfo.EditedDataRows.RemoveAll(Function(x) x.InsertUpdateOrDelete = DbInsUpdateDelType.Insert)
            args.SqlTableEditorSaveDataTaskInfo.EditedDataRows.RemoveAll(Function(x) x.InsertUpdateOrDelete = DbInsUpdateDelType.Update)
    
        Catch ex As Exception
             Throw New XFException($"{Environment.NewLine}{Me.GetType().ToString()}.{System.Reflection.MethodBase.GetCurrentMethod().Name}(): {ex.Message}:{Environment.NewLine}{strSql}", ex)
        End Try
      
      Return saveDataTaskResult
    End Function
    
    private function ValidateRecord(si As SessionInfo, args As DashboardExtenderArgs, row As XFEditedDataRow) As String
      Dim strValidationMsg as String = String.Empty
      'validation code here...
      
      return strValidationMsg
    End Function
    
    
    Private Function GetNextpKTheId(si As SessionInfo) As String
        Dim pKTheId As String = String.Empty
      Dim strSql as String = String.Empty
    
        Try
        strSql = "SELECT COALESCE(MAX(pKTheId), 0)+1 as NextpKTheId From XFW_CustomTable"
        Using DbConn As DbConnInfo = BRApi.Database.CreateApplicationDbConnInfo(si)
          pKTheId = BRApi.Database.ExecuteSql(DbConn, strSQL, True).Rows(0).Item("NextpKTheId")
        End Using
         Catch ex As Exception
            Throw New XFException($"{Environment.NewLine}{Me.[GetType]().ToString()}.{System.Reflection.MethodBase.GetCurrentMethod().Name}(): {ex.Message}:{Environment.NewLine}{strSql}", ex)
        End Try
    
        Return pKTheId
    End Function